Talk briefly about anonymous inner class constructors in Java

  • 2020-04-01 04:21:16
  • OfStack

Let's see if the following code compiles well:


public static void main(String[] args) {
List l1 = new ArrayList();
List l2 = new ArrayList(){};
List l3 = new ArrayList(){{}};
System.out.println(l1.getClass() == l2.getClass() );
System.out.println(l2.getClass() == l3.getClass() );
System.out.println(l1.getClass() == l3.getClass() );
}

The answer is that it can be compiled and output three false. L1 is easy to understand. It just declares one

ArrayList object, so what is l2, l3?

L2 is an anonymous inner class object that inherits the ArrayList.

The l3 statement is a little weird, with two curly braces, but we'll see that this is also the definition of an anonymous inner class, and the code looks like this:


class Sub extends ArrayList {
{
//Initializes the code block
}
}
List l3 = new Sub();

You see, it's just one more block of initializing code, which is a constructor. Of course, there can be more than one construction block in a class. The following code can be compiled:

List l4 = new ArrayList(){{}{}{}} {}}};

Although an initializer block can be used as the constructor of an anonymous inner class, its constructor still carries out special handling. It directly calls the coreference constructor of the parent class when initializing, and then calls its own code block, for example:


List l5 = new ArrayList(5){
{
System.out.println(" I'm an anonymous inner class ");
}
};

Is equivalent to:


class Sub extends ArrayList{
{
System.out.println(" I'm an anonymous inner class ");
}
Sub(int num){
super(num);
}
}
List l5 = new Sub(5);

Let's look at some sample code


package testtest; 
 
public class Main { 
 
  public static void main(String[] args) { 
    InnerTest inner = new InnerTest(); 
    Test t = inner.get(3); 
    System.out.println(t.getI()); 
  } 
} 
 
class Test { 
 
  private int i; 
 
  public Test(int i) { 
    this.i = i; 
  } 
 
  public int getI() { 
    return i; 
  } 
} 
 
class InnerTest { 
 
  public Test get(int x) { 
    return new Test(x) { 
 
      @Override 
      public int getI() { 
        return super.getI() * 10; 
      } 
    }; 
  } 
} 

When compiled, you get four class files: test.class, innertest.class, InnerTest$1.class, and main.class. It is easy to see that the main.class is the class file of the Test class, the test.class is the class file of the superclass Test, and the innertest.class is the class file of the InnerTest.


Related articles: