Pergunta

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 ?

Foi útil?

Solução

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
}

Outras dicas

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

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.

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

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

    }
}

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();   
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top