我一直在研究Java语言规范here(而不是我应该喝啤酒),我很好奇方法可以包含什么。规范声明方法体可以包含块
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只能在顶级类或接口中定义”......任何解释?
答案 0 :(得分:6)
哦,是的,你可以在方法体内声明一个类。 : - )
class A {
public void doIt() {
class B {}
B b = new B();
System.out.println(b.getClass());
}
}
答案 1 :(得分:4)
你已经很好地观察了接口不再工作了。原因是你正在寻找一个非常古老的语法版本。它看起来已经超过10岁了。看一下Java 6的语法(您可能正在测试的内容):
http://www.it.bton.ac.uk/staff/rnb/bosware/javaSyntax/rulesLinked.html#BlockStatement
你会看到封闭声明:
块语句: LocalVariableDeclarationStatement ClassDeclaration 声明
答案 2 :(得分:1)
具有内部类声明的块的示例:
public class Test {
static
{
class C {}
C c = new C();
}
}
虽然我怀疑你会找到一个用例......
答案 3 :(得分:1)
正如其他人所说,你可以在方法中声明一个类。一个用例是使用它作为匿名内部类的替代。匿名内部类有一些缺点;例如,您不能在匿名内部类中声明构造函数。对于在方法中本地声明的类,您可以。
这是一个愚蠢的例子,并没有真正说明你为什么要这样做,但至少你怎么做。
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);
}
答案 4 :(得分:1)
这些被称为本地类。我偶尔使用它,但它并不是必需品。
编辑:本地类可以是静态的,如果它出现在静态上下文中,例如,在静态方法中。
根据规范的措辞, local / inner / anno classe 仅表示class
,而不是interface
。