您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

java中匿名内部类的构造方法调用

2025/12/25 16:48:26发布24次查看
与人讨论匿名内部类的构造方法问题,自己写代码看看原理到底是什么样子的。因为类是匿名的,所以就无从创建一个同名的构造方法了。但是可以直接调用父类的构造方法。测试代码如下:
java代码
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; } }; } }
编译之后得到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。
首先javap -c innertest$1
java代码
compiled from "main.java" class testtest.innertest$1 extends testtest.test{ final testtest.innertest this$0; testtest.innertest$1(testtest.innertest, int); code: 0: aload_0 1: aload_1 2: putfield #1; //field this$0:ltesttest/innertest; 5: aload_0 6: iload_2 7: invokespecial #2; //method testtest/test."<init>〈init〉":(i)v 10: return public int geti(); code: 0: aload_0 1: invokespecial #3; //method testtest/test.geti:()i 4: bipush 10 6: imul 7: ireturn } </init>
很明显,虽然我们看来是匿名内部类,但编译的时候给这个类指定了名字
innertest$1,而且看出来是继承自test:
java代码
class testtest.innertest$1 extends testtest.test
而且在这个类有构造方法:
java代码
testtest.innertest$1(testtest.innertest, int);
这里也很容易理解,两个参数,一个是匿名内部类的外部类引用直接传了进来,这也是我们能在内部类中直接访问外部类成员的实现原理。另外一个就是int类型的参数了。也就是说其实编译器自动的给我们添加了带参数的构造方法。继续往下看:
7: invokespecial #2; //method testtest/test."<init>":(i)v
这就是调用父类的构造方法了 。
接下来 ,我们 只要看 innertest中 get方法 的 实现就可以了 :
csharp代码
compiled from "main.java" class testtest.innertest extends java.lang.object{ testtest.innertest(); code: 0: aload_0 1: invokespecial #1; //method java/lang/object."<init>〈init〉":()v 4: return public testtest.test get(int); code: 0: new #2; //class testtest/innertest$1 3: dup 4: aload_0 5: iload_1 6: invokespecial #3; //method testtest/innertest$1."<init>〈init〉":(ltesttest/innertest;i)v 9: areturn } </init></init><pre></pre>
到这里一切都清楚了,innertest中对待匿名内部类和对待普通类一样,
先是
csharp代码
0: new #2; //class testtest/innertest$1
然后调用其构造方法:
java代码
6: invokespecial #3; //method testtest/innertest$1."〈init〉":(ltesttest/innertest;i)v<pre></pre>
7e51f00a783d7eb8f68358439dee7daf303f424bee22cca8251db2163a7ef0737e51f00a783d7eb8f68358439dee7dafok,一切都清楚了 。0c6dc11e160d3b678d68754cc175188a303f424bee22cca8251db2163a7ef073
更多java中匿名内部类的构造方法调用。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product