Java语言规范 – 无法理解’BlockStatement’

我一直在这里检查Java语言规范(相反,我应该喝啤酒),我很好奇一个方法可以包含什么。 规范声明方法体可以包含块

MethodBody: Block 

‘Block’包含’BlockStatements’的地方。 ‘BlockStatement’规则如下所示:

 BlockStatement : LocalVariableDeclarationStatement ClassOrInterfaceDeclaration [Identifier :] Statement 

我可以理解’LocalVariableDeclarationStatement’

 [final] int x, y, z; 

但是,我不明白为什么 ‘ClassOrInterfaceDeclaration’规则存在。 此规则如下所示:

 ClassOrInterfaceDeclaration: ModifiersOpt (ClassDeclaration | InterfaceDeclaration) ClassDeclaration: class Identifier [extends Type] [implements TypeList] ClassBody InterfaceDeclaration: interface Identifier [extends TypeList] InterfaceBody 

这里发生了什么 – 你肯定不能在一个块中声明一个类或接口? 有人可以帮助解释这种混乱吗?

更新 :我可以在方法中定义一个类,但以下方法不起作用:

 public class Foo { public void doFoo() { interface dooJa { int bar(); } } } 

编译器抱怨说“成员接口dooJa只能在顶级类或接口中定义”……任何解释?

你已经很好地观察了接口不再工作了。 原因是你正在寻找一个非常古老的语法版本。 它看起来已经超过10岁了。 看一下Java 6的语法(您可能正在测试的内容):

http://www.it.bton.ac.uk/staff/rnb/bosware/javaSyntax/rulesLinked.html#BlockStatement

您将看到封闭声明:

BlockStatement:LocalVariableDeclarationStatement ClassDeclaration Statement

哦,是的,你可以在方法体内声明一个类。 🙂

 class A { public void doIt() { class B {} B b = new B(); System.out.println(b.getClass()); } } 

具有内部类声明的块的示例:

 public class Test { static { class C {} C c = new C(); } } 

虽然我怀疑你会找到一个用例…

正如其他人所说,你可以在方法中声明一个类。 一个用例是使用它作为匿名内部类的替代。 匿名内部类有一些缺点; 例如,您不能在匿名内部类中声明构造函数。 使用方法在本地声明的类,您可以。

这是一个愚蠢的例子,并没有真正说明你为什么要这样做,但至少你怎么做。

 public Runnable createTask(int a, int b) { // Method-local class with a constructor class Task implements Runnable { private int x, y; Task(int x, int y) { this.x = x; this.y = y; } @Override public void run() { System.out.println(x + y); } } return new Task(a, b); } 

这些被称为本地类。 我偶尔使用它,但它并不是必需品。

编辑:本地类可以是静态的,如果它出现在静态上下文中,例如,在静态方法中。

从规范的措辞来看, local / inner / anno classe总是意味着只有class ,而不是interface