I would like to understand the strange behavior that I came across with anonymous classes.
I have a class that calls a protected method inside its constructor (I know the bad design, but this is another story ...)
public class A { public A() { init(); } protected void init() {} }
then I have another class that extends A and overrides init() .
public class B extends A { int value; public B(int i) { value = i; } protected void init() { System.out.println("value="+value); } }
If the code
B b = new B(10);
I get
> value=0
and this was expected because the superclass constructor is called before B ctor, and then value is still.
But when using an anonymous class like this
class C { public static void main (String[] args) { final int avalue = Integer.parsetInt(args[0]); A a = new A() { void init() { System.out.println("value="+avalue); } } } }
I would expect to get value=0 , because it should be more or less equal to class B : the compiler automatically creates a new class C$1 , which extends A and creates instance variables to store local variables that are referenced in methods of an anonymous class that simulate closure etc.
But when you run this, I got
> java -cp . C 42 > value=42
Initially, I thought that this was due to the fact that I used java 8, and maybe when introducing lamdbas they changed the way of anonymous classes implemented under the hood (you no longer need final ), but I also tried with java 7 and got one same result ...
Actually, looking at the byte code with javap , I see that B is
> javap -c B Compiled from "B.java" public class B extends A { int value; public B(int); Code: 0: aload_0 1: invokespecial #1 // Method A."<init>":()V 4: aload_0 5: iload_1 6: putfield #2 // Field value:I 9: return ...
and for C$1 :
> javap -c C\$1 Compiled from "C.java" final class C$1 extends A { final int val$v; C$1(int); Code: 0: aload_0 1: iload_1 2: putfield
Can someone tell me why this difference is? Is there a way to reproduce the behavior of an anonymous class using "normal" classes?
EDIT: to clarify the question: why does initializing anonymous classes violate the rules for initializing any other class (where the super constructor is called before setting any other variable)? Or is there a way to set the instance variable in class B before running the superstructor?