我正在阅读Java库中的一些源代码,在这里我很困惑;
这段代码来自jaxb库中的Document.java,而ContentVisitor是同一个包中的一个接口,我们如何使用新关键字创建接口的实例?这不是违法的吗?
public final class Document {
.
.
private final ContentVisitor visitor = new ContentVisitor() {
public void onStartDocument() {
throw new IllegalStateException();
}
public void onEndDocument() {
out.endDocument();
}
public void onEndTag() {
out.endTag();
inscopeNamespace.popContext();
activeNamespaces = null;
}
}
在代码中,您没有创建接口的实例。相反,代码定义了一个实现接口的匿名类,并实例化该类。
该代码大致相当于:
public final class Document {
private final class AnonymousContentVisitor implements ContentVisitor {
public void onStartDocument() {
throw new IllegalStateException();
}
public void onEndDocument() {
out.endDocument();
}
public void onEndTag() {
out.endTag();
inscopeNamespace.popContext();
activeNamespaces = null;
}
}
private final ContentVisitor visitor = new AnonymousContentVisitor();
}
它是有效的。它被称为匿名类。参见此处
我们已经看到了定义和实例化匿名类的语法示例。我们可以将该语法更正式地表示为:
new class-name ( [ argument-list ] ) { class-body }
或:
new interface-name () { class-body }
它被称为实现该接口的anonymous
类型/类。看看教程-本地和匿名内部类。
该声明实际上创建了一个新的匿名类,该类实现了ContentVisitor
接口,然后实现了该给定范围的实例,并且完全有效。
java中有一种叫做匿名类的东西http://www.java2s.com/Code/Java/Class/Anonymous-class.htm
请注意大括号打开的位置-您正在声明一个内部对象(称为anonymous class
),该对象当场实现ContentVisitor
和所有必需的方法!
它是内联接口实现。这里的想法是让编译器生成一个实现接口的匿名类。然后,对于接口中定义的每个方法,您可以(可选)提供一个具有适当签名的方法,该签名将用作接口方法的实现。
它是新的Oxygene语法,添加到语言中,使Oxygene程序员能够像Java程序员一样处理这些基于接口的事件。
您实际上刚刚以匿名的方式提供了这个接口的实现。这很常见,当然也是可能的。请查看此处以获取更多信息。
由于问题仍然是实际的,Java 8引入了lambda。我必须提一下。Lambda与AIC相比有几个优势。
- 可读性/引入函数式编程
- 在某些情况下性能
但是lambda和AIC的范围不同。您不能创建Lambda的实例并获得对Lambda本身的引用。