ServiceLoader类是从1.6版本以后出现的,它实现了Iterable<S>接口。
它可以使得使用者通过配置文件来获得想要的子类。这一点是非常棒的。Hadoop的FileSystem类的中就使用了该类。
我们看一个例子来学习ServiceLoader这个类。
抽象类
package test;
public abstract class testServiceLoader {
public abstract void say();
}
子类HEHE:
package test;
public class HEHEtestServiceLoader extends testServiceLoader{
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("HEHE");
}
}
子类HAHA:
package test;
public class HAHAtestServiceLoader extends testServiceLoader{
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("HAHA");
}
}
这个时候,在src目录下新建个目录META-INF/services,再在这个新建的文件夹下新建一个文件,命名应是抽象类或者接口的全部名字。本例中,新建文件名 test. testServiceLoader,里面写上内容:
#需要加载的子类
test.HAHAtestServiceLoader
test.HEHEtestServiceLoader
编写main函数进行测试:
package test;
import java.util.ServiceLoader;
public class Main {
public static void main(String[] args) {
ServiceLoader<testServiceLoader> sl = ServiceLoader
.load(testServiceLoader.class);
for(testServiceLoader tsl: sl){
tsl.say();
}
}
}
运行之,发现配置文件中子类的say方法都被调用,OK。
JDK文档中还提到了该类有reload()方法。该方法用于清楚加载器的缓存,并重新加载。其实ServiceLoader类最为重要的还是load()方法。
对该类的思考:在阅读Hadoop源码过程中,感觉到使用该类可以有更好的扩展性。这样,仅仅需要更改配置文件即可。