Java Language Specification - Cannot understand 'BlockStatement'

北城余情 提交于 2019-12-21 07:28:09

问题


I've been examining the Java Language Specification here (instead I should be out having a beer) and I am curious about what a method can contain. The specification states a method body can contain a block

MethodBody:
    Block

Where a 'Block' contains 'BlockStatements'. The 'BlockStatement' rule looks like this:

BlockStatement : 
    LocalVariableDeclarationStatement
    ClassOrInterfaceDeclaration
    [Identifier :] Statement

I can understand the 'LocalVariableDeclarationStatement' which could be

[final] int x, y, z;

However, I don't get why the 'ClassOrInterfaceDeclaration' rule is there. This rule looks like:

ClassOrInterfaceDeclaration: 
    ModifiersOpt (ClassDeclaration | InterfaceDeclaration)

ClassDeclaration: 
    class Identifier [extends Type] [implements TypeList] ClassBody

InterfaceDeclaration: 
    interface Identifier [extends TypeList] InterfaceBody

What's going on here - You can't declare a class or interface within a block surely? Can someone help elucidate this confusion please?

Update: I can define a class within a method, but the following won't work:

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

The compiler complains stating "The member interface dooJa can only be defined inside a top-level class or interface"... any explanations?


回答1:


You've made a good observation about interfaces not working anymore. The reason is you that are looking at a very old version of the grammar. It looks to be over 10 year old. Take a look the grammar for Java 6 (what you are probably testing with):

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

You will see blockstatement:

BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement




回答2:


Oh yes you can declare a class inside a method body. :-)

class A {

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

}



回答3:


An example for a block with an inner class declaration:

public class Test {

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

Although I doubt you'll find a use case...




回答4:


As others have said, you can declare a class inside a method. One use case of this is to use this as an alternative for an anonymous inner class. Anonymous inner classes have some disadvantages; for example, you can't declare a constructor in an anonymous inner class. With a class declared locally in a method, you can.

Here's a silly example that doesn't really show why you'd want to do this, but at least how you could do it.

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);
}



回答5:


These are called local classes. I use it occasionally, but it's not really a necessity.

Edit: a local class can be static, if it appears in a static context, for example, within a static method.

From the wording of the spec, local/inner/anno classe always means class only, not interface.



来源:https://stackoverflow.com/questions/6637229/java-language-specification-cannot-understand-blockstatement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!