java 匿名类 反编译_一点点捋,什么叫内部匿名类

effa8fbe7c44bf939c555676071c97a5.png

前言

这是速读系列的第4篇文章,内容是一起聊一聊内部匿名类,以及内部匿名类使用外部变量为啥要加final。

引子

小A:MDove,我最近在学习匿名内部类的时候有点懵逼了?咋还起了个这么洋气的名字?啥是内部匿名类啊?为啥它引用外部变量还得加final?还不能重新赋值?

MDove:哎呦,叭叭的,问题还挺多。话说回来,内部匿名类的确是一个很别扭的存在。那咱们今天就好好聊一聊内部匿名类,好好从源头解一解你的疑问。

啥是内部匿名类

MDove:咱们先写一个普通的内部匿名类的简单demo:

publicclassMain{publicstaticvoidmain(String[] args){final String name = "Haha";new FunLisenter() {@Overridepublicvoidfun(){System.out.println(name); } }.fun(); }}// 外部接口publicinterfaceFunLisenter{voidfun();}

MDove:先解答你第一个问题,啥是内部匿名类。上述demo中的:

new FunLisenter() {@Overridepublicvoidfun(){System.out.println(name); }}

这就是内部匿名类。

小A:啊?它不就是普通的new么?咋还成内部匿名类了?

MDove:它就是普通的new?!!!你怎么学的Java!!接口能被new么!大声告诉我,接口能被new么?!

小A:不能!…不…能…能吧?这不new出来了…

MDove:接口不能new!为什么这里被new出来了?因为它是匿名内部类,它是特殊的存在!

小A:(小声哔哔…)特殊在哪?

MDove:Java语言规定,接口不能被new!既然这是“甲鱼的臀部”,那么new FunLisenter()…就一定不是我们表面上看到的new!接口!!不给你扯犊子,直接上编译后的.class文件:

1384cd506382f3310679929939b1a0c4.png

MDove:瞪大你的眼,仔细看!有什么不同?

小A:咦?怎么2个java文件编译后出来了3个class文件?

MDove:这就是特殊的存在,我们反编译这个特别的Main$1.class文件:

finalclassMain$1 implementsFunLisenter{Main$1() { }publicvoidfun(){ System.out.println("Haha"); }}

MDove:这很清晰吧?看明白了么?

小A:嗯??一个奇怪的类实现了我们的FunLisenter接口??难道我new的FunLisenter就是new的这个奇怪的Main$1类么?

MDove:呦,这么快反应过来了?再深入思考一下。为啥叫做匿名,是不是有点感觉了?对于我们java层面来说,这个类压根就看不到。

小A:那它为啥要叫内部类呀?

MDove:啊?Main$1,不叫内部类叫啥类?你有没有编译过含有内部类的类?内部类的class文件就是这样啊!

小A:哦哦,好像还真是这样!那也就是说之所以被称之为内部匿名类,是因为:在编译阶段,编译器帮我们以内部类的形式,帮我们implement我们的接口,因此我们才可以以new的方式使用。

MDove:没错,你理解的很到位。

小A:对了,我还听说过一个名词,好像叫做:内部匿名类会持有外部对象的引用…这是啥意识?

内部匿名类会持有外部对象的引用

MDove:呦,都了解的这么多了?关于这个话题,暂时先不开展。后续我会专门好好整理一遍内部,好好帮你理解一下这句话,以及这句话背后所带来的问题。这里先简单写段代码,你可以先看看,解解闷。

publicclassMain{

publicstaticvoidmain(String[] args){Main main = new Main(); main.fun(); }publicvoidfun(){new FunLisenter() {@Overridepublicvoidfun(){ } }.fun(); }}

MDove:直接看,反编译后的匿名内部类:

classMain$1 implementsFunLisenter{

Main$1(Main var1) {this.this$0 = var1; }publicvoidfun(){}}

MDove:OK,这个话题就此打住,已经超出了本次文章的范围。不过既然你开了口,下一次我们来好好聊一聊内部匿名类持有外部引用,造成内存泄漏的问题~

剧终

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值