ServiceLoader

 最近在看Java编程思想的14章,也就是RRTI, 一开始因为多态,比如三角形是形状的一种,也就是说三角形继承自形状,形状自身有画的行为,三角形在自己的方法中覆盖(override)或者也说(覆写)了画的行为,因为自己要画的形状指定是三角形了。在我们创建一个三角形对象时,可以将其向上转型为形状,然后我们针对形状进行编程。oops:OOP的原则之一,针对接口编程。那么我们现在用这个形状调用画方法,会发现画的仍然是三角形,而非因为当前引用是形状就调用形状的画方法。现在我们会思考:在三角形向上转型的过程之后,所获取的形状引用,只能调用形状的方法,那三角形新添加的方法,就会没有办法调用。但是此时形状引用确实指向的是一个三角形对象。这时们应该怎么办?在运行时,我们是否有方法与手段来获取当前引用的类型信息。答案是肯定的。我们可以用该引用的getClass()方法,来生成一个Class对象,该对象包含了你想知道的所有的类型信息(方法,域,构造器等等)。

同样的,也提供了Class.forName(),参数为自己想要装载的类的名字或者类名.class来装载类,生成Class对象。再想想假如我们想装载一个类,但是我们根本不知道这个类的类名是什么,那么我们需要怎么做?

就目前我看到了一种实现方案,那就是ServiceLoader的load方法,其参数为一个Class对象。假如你有一个字典小程序,里面添加了常用的词典,但是某一天你想要添加一些与考古,与计算机等相关的词典。这个时候如果我们去修改原有程序的代码,让其实现加载这些字典的功能是不现实的,因为如果某一天你可能因为需要还会需要添加别的字典,比如金融相关,这时再去改这些代码。那么怎么实现才能不必每次都需要改写代码?

我们可以让ServiceLoader的load方法加载一个Dictionary.class。该Dictionary包含了一个字典应提供的所有接口,我们的考古,计算机,金融系相关的词典都必须实现Dictionary,并且在META-INF/services包中添加一个文件,该文件名与Dictionary类的全名相同,在该文件中写入计算机,金融等这些字典类的全名(即包名+类名),这样ServiceLoader就可以将所有的字典,只要实现了Dictionary的字典,都加载到程序中。(该例子来源于Java关于ServiceLoader的教程上,上面有这个例子的所有源码。以及构建方式)。

 

posted @ 2016-09-10 14:52  Pool  阅读(78)  评论(0)    收藏  举报