javaanonymous-class

Java Anonymous class redefining


This is simple java program of anonymous class where class is redefined (not interface) as anonymous class.

class Anonymous {
    int i = 10;
    void main() {
        System.out.println("Anonymous Main " + i);
    }

    void setI(int i) {
        System.out.println("under set");
        this.i = i;
    }

    void main2() {
        setI(30);
        System.out.println("Main 2's " + i);
    }

}

public class Runner {

    public static void main(String[] args) {
        Anonymous a = new Anonymous() {
            int i = 20;

            @Override
            void setI(int i) {
                System.out.println("Over set");
                this.i = i;
            }

            @Override
            public void main() {
                setI(0);
                System.out.println("Redefined Anonymous Main " + i);
            }
        };
        a.main();
        a.main2();
    }
}

Output:-

Over set
Redefined Anonymous Main 0
Over set
Main 2's 10

I have few questions:

  1. In main2, why it has access to i with 10 value?

  2. Why object a has two copies of i?

  3. If has, then when calling setI why there is not two copies of setI?

  4. Why main2 access to redefined setI and not i?

  5. What exactly is Java doing?


Solution

  • I think you should start from reading this part of Oracle guides. Then I hope it will all be a bit more transparent for you. The thing you should understand is that i in the parent and i in the child are not the same at all.

    So, regarding your questions:

    1. main2() is not overridden, therefore JIT will use the parent's version of the method using its visibility context of course. The parent does not know about the child's variable i. Only the child knows that it has hidden the parent field. Therefore your parent prints it's i (not the same as child's i), but the setI is overridden, and thus setI sets the value of the child's i.

    2. Because this is how Java works :) Provided link already

    3. Because the method in the child overrides the one in the parent. It is not hiding in this case, it is true polymorphism.

    4. Becuase you are invoking main2() on object that has overridden setI. Therefore it invokes overridden version of setI. Again - when i is modified inside main2, it is not the same i as in the child, and main2() in parent has no access to child's i.

    5. Just obeying the JLS :) This is expected behavior, I hope now you understand why.