这是一个困扰我一段时间的问题。
在像 Jersey 这样的框架中,我们有接口,我们可以对其进行子类化以向程序添加一些功能。 例如,要在RESt应用程序中添加请求过滤,我们可以实现ContainerRequestFilter,然后瞧,我们得到了身份验证。
我的问题是框架/库如何知道我们有它的接口之一的子类?
根据我的理解,您不能实例化接口,只能实例化其子类,例如:
public interface Greeter{
void sayHi();
}
public class SpanishGreeter implements Greeter{
@override
void sayHi(){
System.out.println("Hola");
}
}
public class Controller{
public void main(String[] args){
//We must know the name of subclass to instantiate?
Greeter spanishG = new SpanishGreeter();
}
}
您要查找的是类路径扫描。
这不是一项微不足道的任务,顾名思义:您基本上需要扫描类路径并加载找到的每个类(尽管典型的实现将允许您将搜索限制在某些包及其子包上,以防止事情变得非常疯狂(。
Java 语言中没有特殊的技巧可以使这项任务变得容易。
好消息是你不需要从头开始编写它,因为像Spring这样的框架已经内置了它,或者如果你想拥有完整的低级控制,你可以使用像Reflections这样的专用库。
我认为关键字实例对此有所帮助。
System.out.println(spanishG instanceof Greeter); // true
这是由于多态性而发生的。你提到的代码
Greeter spanishG = new SpanishGreeter();
它有父级的参考(在你的例子中是接口(。在运行时,它会检查天气,如果是一个子类实现该方法,如果是,则调用子类行为。在你的类中,你在运行时用子类实例化,JVM知道你已经提供了实现。