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只能在顶级类或接口中定义”。是否有一个原因?或者我错过了我犯的错误?
答案 0 :(得分:4)
Java语言规范没有告诉你为什么它的设计是这样的,但它确实描述了什么是不允许的和什么是不允许的。
method body具有以下形式
MethodBody:
Block
;
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());
}
}