1
votes

I have three questions.

1- How can non-final fields be used in a anonymous class class if their value can change?

class Foo{
    private int i;
    void bar(){
        i = 10
        Runnable runnable = new Runnable (){
            public void run (){
                System.out.println(i); //works fine
            }//end method run
        }//end Runnable
    }//end method bar
}//end class Foo 

2- Why static nested classes can't be declared inside methods as inner classes can uner the name of (local classes)?

Class Foo {
    void bar(){
        class LocalClass{ //static nested classes are NOT allowed here
            //define members
        }//end class LocalClass
    }//end method bar
}//end class Foo

3- Why can't an inner class define static members except static final fields?

class Foo {
    class Bar{
        static int x; //NOTallowed
        static final int y; //allowed

        static void doSomething(){} //NOT allowed
    }//end class Bar
}//end class Foo

For the third question, I know that inner classes are associated with instances of their outer classes, but this is still not convincing answer for me. We could just use somthing like new Foo().Bar.doSomething(); if static methods were allowed.

1

1 Answers

1
votes

1- How can non-final fields be used in a anonymous class class if their value can change?

class Foo{
    private int i;
    void bar(){
        i = 10;
        Runnable runnable = new Runnable (){
            public void run (){
                System.out.println(i); //works fine
            }//end method run
        }//end Runnable
    }//end method bar
}//end class Foo 

Lets break the code is equivalent to -

class Foo{
        private int i;
ublic static void bar() {
    i = 10;
    Runnable r = new ARunnable();
    r.run();
}

private static class ARunnable implements Runnable {

    @Override public void run() {
        System.out.println(i);
    }
}
}

The declared anonymouse Runnable class is essentially a nested class in the method bar() which is local to the function bar(). Thus the anonymouse class has access to the fields of parent class. But if the variable i was local to the function bar(), we don't want to allow any other function to access it. For function of inner class in method bar(), we can allow to read it but not change it, otherwise it would look odd and break the ethics of local.

class Foo{
   // private int i;
    void bar(){
        final int i = 10;  // adding `final` as i is local to function bar 
        Runnable runnable = new Runnable (){
            public void run (){
                System.out.println(i); 
            }//end method run
        }//end Runnable
    }//end method bar
}/  

2- Why static nested classes can't be declared inside methods as inner classes can ?

As the java specification says:

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.

If we declare a local class inside a block, it is to operate in the context of the enclosing block. No block(method) knows about the local instances of another block(method), as anything declared inside a block is to be local to that block. So the block(method) to which it is local should be the only to be able to instantiate it. It would not make any sense declaring it as static. Same thing is true for class access modifier private, public and protected.

3-Why can't an inner class define static members except static final fields?

inner classes are non-static. A nested static class is called a nested class, not an inner class. It is to operate in the context of the enclosing instance. Somehow, allowing static variables and methods contradicts this motivation. However, for more elaboration on answers to this question: see here and here.