Java中有“本地接口”这样的东西吗?

时间:2014-02-02 21:18:54

标签: java interface local-class

Java允许我定义本地抽象类,如下例所示:

public class Foo {

    public void foo() {
        abstract class Bar {          // Bar is a local class in foo() ...
            abstract void bar();
        }

        new Bar() {                   // ... and can be anonymously instantiated
            void bar() {
                System.out.println("Bar!");
            }
        }.bar();
    }
}

出于某种原因,当我尝试定义“本地接口”而不是本地类时,如下所示:

public class Foo {

    public void foo() {
        interface Bar {           // Bar was supposed to be a local interface...
            void bar();
        }

        new Bar() {               // ... to be anonymously instantiated
            void bar() {
                System.out.println("Bar!");
            }
        }.bar();
    }
}

Java抱怨“成员接口Bar只能在顶级类或接口中定义”。是否有一个原因?或者我错过了我犯的错误?

3 个答案:

答案 0 :(得分:4)

Java语言规范没有告诉你为什么它的设计是这样的,但它确实描述了什么是不允许的和什么是不允许的。

method body具有以下形式

MethodBody:
    Block 
    ;

where Block is

Block:
    { BlockStatementsopt }

BlockStatements:
    BlockStatement
    BlockStatements BlockStatement

BlockStatement:
    LocalVariableDeclarationStatement
    ClassDeclaration
    Statement

因此允许类声明,但接口不是。


我们可以争辩说,从调用者的角度来看,拥有本地接口并不是很有用。它没有任何用途。接口用于描述行为,但由于接口是本地接口,因此没有调用者可以使用它。您也可以在类中定义和实现行为。

答案 1 :(得分:4)

在JLS中根本没有它的定义。它只是不存在。

至于一个微弱的原因,根据JLS 14.3

  

所有本地类都是内部类(第8.1.3节)。

界面不能是内部的(JLS 8.1.3):

  

成员接口(第8.5节)是隐式静态的,因此它们从不被视为内部类。

所以我们不能有本地接口。

我想,除了@SotiriosDelimanolis发现InterfaceDeclaration不是BlockStatement之外,我想这是。

答案 2 :(得分:2)

本地接口(和枚举)已随记录类功能引入:

不幸的是,此功能在文档中有点模糊 - 但它有效。

两个版本都允许编写如下代码:

public class Main {

    public int foo() {

        interface Experimentable {
            int bar();
        }

        Experimentable e = new Experimentable() {
            @Override
            public int bar() {
                return 0;
            }
        };

        return e.bar();
    }

    public static void main(String[] args) {
        System.out.println(new Main().foo());
    }

}