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开发者_如何学Go '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?
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());
}
}
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
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...
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);
}
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
.
精彩评论