1

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.

kzidane
  • 753
  • 3
  • 11
  • 29

1 Answers1

1

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.

Community
  • 1
  • 1
Sage
  • 15,290
  • 3
  • 33
  • 38
  • "Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.". So actually a static nested class and an inner class are both said to be nested classes. Anyways thanks for your answer. – kzidane Oct 07 '13 at 00:31
  • To answer your first question i answered assuming inner class(non static nested class) as it signifies it's usage more accurately. – Sage Oct 07 '13 at 00:36
  • Did i get your first question right ? for some reason i don't think so. :( – Sage Oct 07 '13 at 00:42
  • I think you didn't. Just for clearing more, if you try to make method **run()** use a non-final local variable to pass to method println(), you get a compilation error. I know the [reason][1] behind this. However, when you use a non-final field, your program compiles without any complains and this makes me a little bit confused when I compare its case with the reason of allowing only final local variables to be used in an anonymous class. [1]http://goo.gl/xHqksx – kzidane Oct 07 '13 at 00:49
  • thanks for clarifying. updated the answer. Hope that everyone will get me what i wanted to say. – Sage Oct 07 '13 at 01:12
  • "Thus the anonymous class has access to the fields of parent class." If we can depend on this, then we can say that the anonymous class has access to the local variables (declared before it) of the method too. And as well as we don't need any function to access a local variable of a method, we don't need any function to access the anonymous class declared in a method (that's where its scope ends — the closing brace of the method body). – kzidane Oct 07 '13 at 10:58
  • sorry. I think you didn't get me. I am bad at explaining thing, uses lot more words than necessary. English is not my native either. :( – Sage Oct 07 '13 at 21:01