初学者对java匿名内部类构造原理的分析 (散分)
学Java 虽然时间不算太长,但是对一些原理性的东西很感兴趣。今天分析了一下匿名内部类调用构造方法的原理,希望高手拍砖。
因为匿名内部类没有名字这个特殊性质,所以我们无从给它指定构造方法,构造方法必须和类名同名,类名都没有,构造方法就无从谈起了。但是匿名内部类可以通过直接调用父类的构造方法实现初始化,当然要求父类构造方法对它父类中定义的成员变量进行初始化。这里用一个例子看创建匿名内部类的时候父类的构造方法到底是如何调用的。
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; } }; }}
Compiled from "Main.java"class InnerTest$1 extends Test{final InnerTest this$0;InnerTest$1(InnerTest, int); Code: 0: aload_0 1: aload_1 2: putfield #1; //Field this$0:LInnerTest; 5: aload_0 6: iload_2 7: invokespecial #2; //Method Test."<init>":(I)V 10: returnpublic int getI(); Code: 0: aload_0 1: invokespecial #3; //Method Test.getI:()I 4: bipush 10 6: imul 7: ireturn}
Compiled from "Main.java"class InnerTest extends java.lang.Object{InnerTest(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: returnpublic Test get(int); Code: 0: new #2; //class InnerTest$1 3: dup 4: aload_0 5: iload_1 6: invokespecial #3; //Method InnerTest$1."<init>":(LInnerTest;I)V 9: areturn}
将我这个理论套到楼主的代码中:
public Test get(int x) { return new /*1、创建匿名类,后面的Test先放放*/ Test(x) /*3、这里将new Test$1()转型成 Test类型,至于这里写成Test(x)的形式,仅仅只是个语法形式而已*/{ @Override public int getI() { //2、从这里开始和普通类一样进行初始化 /*这里应该有个匿名的构造方法 Test$1(int x){ //这里之所以是int类型是因为,JVM自动设置的 Super(x); }*/ return super.getI() * 10; }
[解决办法]
嗯。
像return new Test(x) {
这句,实际上new Text(x)调用的时候,编译器一方面在构造这个匿名的,Test类的子类;另一方面也在生成创建这个匿名类的对象实例的代码。所以,根据Java的后期动态绑定原则,实际上new test()调用了匿名子类的构造方法。
[解决办法]
路过,接点分
[解决办法]
接分
[解决办法]
哦
[解决办法]
ZangXT老师的无私精神真值得大家学习啊。