【问题标题】:Java: Interface with new keyword how is that possible?Java:带有新关键字的接口怎么可能?
【发布时间】:2012-02-27 18:58:26
【问题描述】:

我正在从 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;
    }
}

【问题讨论】:

  • 您可能刚刚发现了 Java 编程语言最强大的功能之一。

标签: java interface


【解决方案1】:

在代码中,您没有创建接口的实例。相反,代码定义了一个实现接口的匿名类,并实例化该类。

代码大致相当于:

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();
}

【讨论】:

  • 感谢这种语法(匿名类)只是让我们免于编写一些额外的代码,还是它还有其他优点或用途?
  • 它省去了编写额外代码和想出名称的麻烦。在上面的例子中,名字更有可能是Document$1
  • @DesignCode:主要是语法糖,但也有独特的卖点。例如,如果在函数内部定义了这样的类,它可以访问在函数内部定义的final变量。
【解决方案2】:

它被称为anonymous 实现该接口的类型/类。看看教程 - Local and Anonymous Inner Classes

【讨论】:

    【解决方案3】:

    该声明实际上创建了一个新的匿名类,该类实现了ContentVisitor 接口,然后是该给定范围的实例,并且完全有效。

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        请注意大括号打开的位置 - 您正在声明一个内部对象(称为 anonymous class),它实现了 ContentVisitor 和所有必需的方法!

        【讨论】:

          【解决方案6】:

          它是内联接口实现。这里的想法是让编译器生成一个实现接口的匿名类。然后,对于接口中定义的每个方法,您可以(可选地)提供一个带有合适签名的方法,该签名将用作接口方法的实现。

          它是新的 Oxygene 语法,添加到语言中以允许 Oxygene 程序员以与 Java 程序员相同的方式处理这些基于接口的事件。

          【讨论】:

            【解决方案7】:

            有效。它被称为匿名类。 See here

            我们已经看到了定义和实例化匿名类的语法示例。我们可以更正式地将该语法表示为:

            new class-name ( [ argument-list ] ) { class-body }
            

            或:

            new interface-name () { class-body }
            

            【讨论】:

              【解决方案8】:

              您实际上只是以匿名方式提供了此接口的实现。这是很常见的,当然也是可能的。查看here 了解更多信息。

              【讨论】:

                【解决方案9】:

                由于问题仍然是实际的,并且 Java 8 引入了 lambda。我必须提到它。 Lambda 与 AIC 相比有两个优势。

                • 可读性/引入函数式编程。
                • 在某些cases 表现中。

                但是 lambda 和 AIC 的作用域不同。您无法创建 Lambda 实例并获取对 lambda 本身的引用。

                【讨论】:

                  猜你喜欢
                  • 2018-07-14
                  • 2014-02-19
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-04-02
                  • 1970-01-01
                  • 2011-01-31
                  • 2013-03-06
                  • 2012-08-24
                  相关资源
                  最近更新 更多