Java语言规范-无法理解';区块语句';
我一直在研究Java语言规范(相反,我应该出去喝杯啤酒),我很好奇一个方法可以包含什么。规范规定方法体可以包含块Java语言规范-无法理解';区块语句';,java,language-features,Java,Language Features,我一直在研究Java语言规范(相反,我应该出去喝杯啤酒),我很好奇一个方法可以包含什么。规范规定方法体可以包含块 MethodBody: Block 其中“块”包含“块语句”。“BlockStatement”规则如下所示: BlockStatement : LocalVariableDeclarationStatement ClassOrInterfaceDeclaration [Identifier :] Statement 我能理解“LocalVaria
MethodBody:
Block
其中“块”包含“块语句”。“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只能在顶级类或接口中定义”。。。有什么解释吗?哦,是的,您可以在方法体中声明一个类。:-)
具有内部类声明的块的示例:
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);
}
您已经很好地观察到接口不再工作。原因是你看到的是一个非常古老的语法版本。它看起来已经超过10年了。看看Java 6的语法(您可能正在使用它进行测试): 您将看到blockstatement: 区块声明: LocalVariableDeclarationStatement 类声明 声明
这些被称为本地类。我偶尔会用它,但这不是必要的 编辑:局部类可以是静态的,如果它出现在静态上下文中,例如在静态方法中
从规范的措辞来看,local/internal/anno classe始终仅表示
类
,而不是接口
好吧,我会。。。我在想什么匿名的内部阶级之类的。谢谢你。顺便说一句,我认为我在Eclipse中尝试这一点是积极主动的。但是,当我使用“public”标识符时,它给了我一个错误,这是不允许的(只有抽象或最终的),但我得到了错误,并假设(未经检查)您无法在方法中定义类或接口。但是,在方法中定义接口对我来说不起作用。在Eclipse中,我得到一个错误:“成员接口dooJa只能在顶级类或接口中定义”。但是,定义一个类确实有效。好吧,您可以始终使用匿名内部类在封闭方法中创建接口的实例,不是吗?但是您将无法返回它(除非您计划返回一个对象),因为外部世界不知道该接口。另外,强制执行方法范围内的契约有什么意义?:)是的,但这似乎不适用于接口,即使语言规范说你也可以定义接口。那就更好了!谢谢你。现在,啤酒在哪里:-)没问题。更准确地说,这里的页面描述了语言规范的不同添加:
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);
}