简单谈谈java中匿名内部类构造函数
先看看下面的代码能不能编译通过:
publicstaticvoidmain(String[]args){ Listl1=newArrayList(); Listl2=newArrayList(){}; Listl3=newArrayList(){{}}; System.out.println(l1.getClass()==l2.getClass()); System.out.println(l2.getClass()==l3.getClass()); System.out.println(l1.getClass()==l3.getClass()); }
答案是能通过编译,输出3个false。l1很容易理解,就是声明了一个
ArrayList对象,那么l2、l3是什么呢?
l2是一个匿名类内部类对象,继承ArrayList;
l3语句有些古怪,带了两个大括号,其实我们这样写就会明白了,这也是一个匿名内部类的定义,它的代码类似如下:
classSubextendsArrayList{ { //初始化代码块 } } Listl3=newSub();
看到了吧,就是多了一个初始化代码块而已,起到构造函数的功能。当然一个类中的构造代码块可以有多个,下面的代码是可以编译的:
Listl4=newArrayList(){{}{}{}};
匿名内部类虽然可以用一个初始化代码块来充当构造函数,但其构造函数还是进行了特殊的处理,它在初始化时直接调用父类的同参构造函数,然后在调用自己的代码块,例如:
Listl5=newArrayList(5){ { System.out.println("我是匿名内部类"); } };
等价于:
classSubextendsArrayList{ { System.out.println("我是匿名内部类"); } Sub(intnum){ super(num); } } Listl5=newSub(5);
我们来看段示例代码
packagetesttest; publicclassMain{ publicstaticvoidmain(String[]args){ InnerTestinner=newInnerTest(); Testt=inner.get(3); System.out.println(t.getI()); } } classTest{ privateinti; publicTest(inti){ this.i=i; } publicintgetI(){ returni; } } classInnerTest{ publicTestget(intx){ returnnewTest(x){ @Override publicintgetI(){ returnsuper.getI()*10; } }; } }
编译之后得到4个class文件:Test.class,InnerTest.class,InnerTest$1.class以及Main.class。容易看出来,Main.class是测试类的class文件,Test.class是超类Test的class文件,InnerTest.class是InnerTest的class文件,最值得关注的就是匿名内部类的class文件InnerTest$1.class。