Java语言规范 - 无法理解'BlockStatement'

时间:2011-07-09 20:15:20

标签: java language-features

我一直在研究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只能在顶级类或接口中定义”......任何解释?

5 个答案:

答案 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