什么场景要用@bean_【176期】面试官:你知道为什么要加 final 关键字了吗?
点击上方“Java面试题精选”,关注公众号
面试刷图,查缺补漏
>>号外:往期面试题,10篇为一个单位归置到本公众号菜单栏->面试题,有需要的欢迎翻阅
阶段汇总集合:001期~150期汇总,方便阅读,不断更新中.....
在开发过程中,由于习惯的原因,我们可能对某种编程语言的一些特性习以为常,特别是只用一种语言作为日常开发的情况。
但是当你使用超过一种语言进行开发的时候就会发现,虽然都是高级语言,但是它们之间很多特性都是不太相同的。
现象描述
在 Java 8 之前,匿名内部类在使用外部成员的时候,会报错并提示 “Cannot refer to a non-final variable arg inside an inner class defined in a different method”:
![](/assets/blank.gif)
但是在 Java 8 之后,类似场景却没有再提示了:
![](/assets/blank.gif)
难道是此类变量可以随便改动了吗?当然不是,当你试图修改这些变量的时候,仍然会提示错误:
![](/assets/blank.gif)
可以看到,当试图修改基本数据类型的变量时,编译器的警告变成了 “Varible 'num' is accessed from within inner class, need to be final or effectively final”,很遗憾,仍然不能修改。相比之下,Kotlin 是没有这个限制的:
![](/assets/blank.gif)
原因分析
从表面上当然看不出什么原因,看看编译器做了什么工作吧!运行 javac 命令后生成了几个 .class 文件:
![](/assets/blank.gif)
不难推断,这个 TestInnerClass$1.class 就是匿名内部类编译后的文件,看看它反编译后是什么内容:
class TestInnerClass$1 extends InnerClass { TestInnerClass$1(TestInnerClass var1, int var2, DataBean var3) { super(var1); this.this$0 = var1; this.val$num = var2; this.val$bean = var3; }
void doSomething() { super.doSomething(); System.out.println("num = " + this.val$num); System.out.println("bean name is: " + this.val$bean.name); }}
原来,匿名内部类也会被当作普通的类处理,只不过编译器生成它构造方法的时候,除了将外部类的引用传递了过来,还将基本数据类型的变量复制了一份过来,并把引用数据类型的变量引用也传递了过来。
因此,基本数据类型的变量当然不能修改了,不然就会跟外部的变量产生不一致,这样的话变量的传递也就变得毫无意义了。
final 关键字除了能让类不能被继承之外,对应到这种场景,就是让变量也不能被重新赋值。
情景对比
但是为什么对于 Kotlin 来说可以在匿名内部类中直接修改基本数据类型的值呢?查看 Kotlin 编译后反编译回来的内容:
public final void useNestedClass(@NotNull final TestNestedClass.DataBean bean) { Intrinsics.checkParameterIsNotNull(bean, "bean"); final IntRef num = new IntRef();//---1 num.element = 1;//---2 String var3 = "before action, num = " + num.element; System.out.println(var3); nestedClass = new TestNestedClass.NestedClass() {public void doSomething() { num.element = 678;//---3 bean.setName("xyz"); String var1 = "num = " + num.element; System.out.println(var1); var1 = "bean name is: " + bean.getName(); System.out.println(var1); } }; nestedClass.doSomething(); String var4 = "after action, num = " + num.element;//---4 System.out.println(var4); }
可以发现,当需要传递基本数据类型的变量时,Kotlin 编译器会将这些数据进行包装,从而由值传递变为引用传递,这样内部的修改当然就不会影响到外部了。
验证一下,当变量不进行传递时,Kotlin 编译器是怎么处理的:
public final void useNestedClass(@NotNull TestNestedClass.DataBean bean) { Intrinsics.checkParameterIsNotNull(bean, "bean"); int num = 1; String var3 = "before action, num = " + num; System.out.println(var3); int num = 678; var3 = "after action, num = " + num; System.out.println(var3); }
哈哈,并没有多此一举,点个赞!
来源:www.jianshu.com/p/acc8d9a67d0c
与其在网上拼命找题? 不如马上关注我们~
什么场景要用@bean_【176期】面试官:你知道为什么要加 final 关键字了吗?相关推荐
- 面试官:对于 JavaScript 的加载问题你怎杨理解?
面试官:"对于 JavaScript 的加载问题你怎杨理解?" 在我们学习 js 引入方式的时候,相信大家都会遇到遇到下方代码这类问题,它的写法和我们引入css的方式基本相同, ...
- 云漫圈 | 腾讯面试,我竟然输给了final关键字
戳蓝字"CSDN云计算"关注我们哦! 作者:乔戈里 来源:程序员乔戈里 腾讯面试现场 ------ final 在 Java 中是一个保留的关键字,可以声明变量.方法.类. 什么是 ...
- 当面试官问我————为什么String是final的?
面试官:你好,能看得清下面这张图吗? 我:可以的. 面试官:恩,好的.呃,你能不能说一说为什么String要用final修饰? 我:final意味着不能被继承或者被重写,String类用final修饰 ...
- 什么场景要用@bean_终于明白为什么要加 final 关键字了!
作者:guanpjhttp://www.jianshu.com/p/acc8d9a67d0c 在开发过程中,由于习惯的原因,我们可能对某种编程语言的一些特性习以为常,特别是只用一种语言作为日常开发的情 ...
- eui加载时间长_面试官:为什么 HashMap 的加载因子是0.75?
有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的时候发现有很多可以去细究的问题,最终是会回归于数学的,如HashMap的加载因子为什么是0.75? 本文主要对以下内容进行介绍: 为什 ...
- 面试官:为什么 HashMap 的加载因子是0.75?
点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源:8rr.co/8V9Q 有很多东西之前在学的时候没怎么注意, ...
- java类加载过程_面试官:java类的加载过程
Java 类加载机制 类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段. 其中类加载过程包括加载.验证.准备.解析和初始化五个阶段. 类的加载 ...
- 面试官:讲讲Bean的加载过程
spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...
- 知乎高赞:如果你是一个 Java 面试官,你会问哪些问题....
注:本文内容选自公众号<Java面试题精选>,内容比较丰富,帮助大家做面试前的准备,可以省不少时间.欢迎收藏点赞,也欢迎去围观原号主! 不断收集整理,汇总网上面试知识点,方便面试前刷题,希 ...
最新文章
- 谷歌被指骗取人脸数据:部分获取方法可疑
- 中断底半部:softirq、tasklet、workqueue
- 使用JDK 13查看TLS配置
- 40种Javascript中常用的使用小技巧【转】
- 最新版的SSM框架spring5.0搭建教程(附源码)
- 蔚来否认关闭硅谷办公室 近期也没有回科创板的计划
- python地址多少位_Python获取IP地址对应的地理位置信息!
- [vb]On Error GoTo 0和On Error resume区别
- 企业信息化投入中咨询服务_嘉萱企业管理咨询服务 让发展中的企业真正实现全面性效益增长...
- windows apache 负载均衡配置 Tomcat集群配置
- Eclipse调试时Application XXX is waiting for the debugger to attach的提示
- yaml 标记语言说明
- oracle学习笔记之pI/sql视频小结
- C的xml编程-libxml2(转)
- SpringBoot结合ActiveMQ(同时支持Queue和Topic)
- 【内部流出,勿做商用】今日教大家如何抢聚划算
- LTE CQI/PMI 上报机制
- MapReduce算法(将数据按照 /OutputData/城市名称/日期(YYYY-MM-dd)/类型(固定Gn)/imsi.txt )
- python 计算list中平均值_python里的list求平均值
- Svn主分支次分支合并和版本回退
热门文章
- html两个div浮动后下一个div怎么换行的问题
- 测试敏捷化 vs 敏捷测试
- 教育部:原则上疫情得到有效控制前,大学生不返校、高校不开学
- [Errno 13] Permission denied: ‘/home/robot/catkin_ws/build‘
- 如何在win 10 家庭版上安装日语语言包
- Mysql 左连接 多个字段
- CSS3 Generator在线工具
- 51单片机_动态数码管显示
- C# 键盘响应事件及键值对照表
- 基于VB6.0的货架数量管理系统