Reputation: 21901
case I
class Outer {
void outerMethod() {
Inner i = new Inner(); //compile error : cannot find symbol
i.innerMethod();
class Inner {
void innerMethod() {
System.out.println("inner class method...");
}
}
}
}
case II
class Outer {
void outerMethod() {
Inner i = new Inner();
i.innerMethod();
}
class Inner {
void innerMethod() {
System.out.println("inner class method...");
}
}
}
there are two separate class files in these two cases. but one is getting compile error and other one is fine. what is the reason for that ?
Upvotes: 4
Views: 79
Reputation: 22446
Local classes have different scope rules. From the JLS, section 6.3:
"The scope of a local class declaration immediately enclosed by a block (§14.2) is the rest of the immediately enclosing block, including its own class declaration. "
In your first example, you call the constructor of Inner class before the scope of this inner class, therefore it is illegal.
TO illustrate this in your code:
void outerMethod() {
// ...
// ...
// Beginning of legal usage scope of the local class
class Inner {
void innerMethod() {
System.out.println("inner class method...");
}
}
// ...
// ...
// End of legal usage scope of the local class
}
Upvotes: 3
Reputation: 8695
In case 1 you have to define a class first and then use it. The reason for this is the context of the class Inner
. Consider this:
class Outer {
void outerMethod() {
Inner i = new Inner(); //compile error : cannot find symbol
i.innerMethod();
final int localVar = 1;
class Inner {
void innerMethod() {
System.out.println("inner class method... localVar = " + localVar );
}
}
Inner i = new Inner(); // No Error
i.innerMethod();
}
}
As you can see, the class Inner
uses local variable defined earlier and though can only be used later on in the code.
Upvotes: 1
Reputation: 926
in case 1 - think of the class as variable declaration (since it only exists in the scope of this method), you are trying to assign variable "inner" when it still not exists, move the class declaration to the top of the method and it will compile.
class Outer {
void outerMethod() {
class Inner {
void innerMethod() {
System.out.println("inner class method...");
}
}
Inner i = new Inner();
i.innerMethod();
}
}
Upvotes: 0
Reputation: 7804
The local inner class must be defined withing the method before using it.
Try this:
class Outer {
void outerMethod() {
class Inner { // Inner class definition
void innerMethod() {
System.out.println("inner class method...");
}
}
Inner i = new Inner(); // No compilation error
i.innerMethod();
}
}
Upvotes: 0
Reputation: 831
In your first case, when you instantiate your Inner
class, it's unknown. Just change the order of your instructions :
void outerMethod() {
class Inner {
void innerMethod() {
System.out.println("inner class method...");
}
}
Inner i = new Inner();
i.innerMethod();
}
Upvotes: 0
Reputation: 172448
Your case II is working because you have done the proper scoping
class Outer {
void outerMethod() {
Inner i = new Inner();
i.innerMethod();
} --> You have the scope change here in this case
class Inner {
void innerMethod() {
System.out.println("inner class method...");
}
}
}
ie, local inner class must be defined before using it.
In the first case when you instantiate your Inner class, it is unknown and hence resulted in compile time error
Upvotes: 1