点击上方“Java面试题精选”,关注公众号

面试刷图,查缺补漏

>>号外:往期面试题,10篇为一个单位归置到本公众号菜单栏->面试题,有需要的欢迎翻阅

阶段汇总集合:001期~150期汇总,方便阅读,不断更新中.....

在开发过程中,由于习惯的原因,我们可能对某种编程语言的一些特性习以为常,特别是只用一种语言作为日常开发的情况。

但是当你使用超过一种语言进行开发的时候就会发现,虽然都是高级语言,但是它们之间很多特性都是不太相同的。

现象描述

在  Java 8 之前,匿名内部类在使用外部成员的时候,会报错并提示 “Cannot refer to a non-final variable arg inside an inner class defined in a different method”


但是在 Java 8 之后,类似场景却没有再提示了:


难道是此类变量可以随便改动了吗?当然不是,当你试图修改这些变量的时候,仍然会提示错误:


可以看到,当试图修改基本数据类型的变量时,编译器的警告变成了 “Varible 'num' is accessed from within inner class, need to be final or effectively final”,很遗憾,仍然不能修改。相比之下,Kotlin 是没有这个限制的:


原因分析

从表面上当然看不出什么原因,看看编译器做了什么工作吧!运行 javac 命令后生成了几个 .class 文件:


不难推断,这个 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 关键字了吗?相关推荐

  1. 面试官:对于 JavaScript 的加载问题你怎杨理解?

    面试官:"对于 JavaScript 的加载问题你怎杨理解?" ​ 在我们学习 js 引入方式的时候,相信大家都会遇到遇到下方代码这类问题,它的写法和我们引入css的方式基本相同, ...

  2. 云漫圈 | 腾讯面试,我竟然输给了final关键字

    戳蓝字"CSDN云计算"关注我们哦! 作者:乔戈里 来源:程序员乔戈里 腾讯面试现场 ------ final 在 Java 中是一个保留的关键字,可以声明变量.方法.类. 什么是 ...

  3. 当面试官问我————为什么String是final的?

    面试官:你好,能看得清下面这张图吗? 我:可以的. 面试官:恩,好的.呃,你能不能说一说为什么String要用final修饰? 我:final意味着不能被继承或者被重写,String类用final修饰 ...

  4. 什么场景要用@bean_终于明白为什么要加 final 关键字了!

    作者:guanpjhttp://www.jianshu.com/p/acc8d9a67d0c 在开发过程中,由于习惯的原因,我们可能对某种编程语言的一些特性习以为常,特别是只用一种语言作为日常开发的情 ...

  5. eui加载时间长_面试官:为什么 HashMap 的加载因子是0.75?

    有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的时候发现有很多可以去细究的问题,最终是会回归于数学的,如HashMap的加载因子为什么是0.75? 本文主要对以下内容进行介绍: 为什 ...

  6. 面试官:为什么 HashMap 的加载因子是0.75?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源:8rr.co/8V9Q 有很多东西之前在学的时候没怎么注意, ...

  7. java类加载过程_面试官:java类的加载过程

    Java 类加载机制 类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段. 其中类加载过程包括加载.验证.准备.解析和初始化五个阶段. 类的加载 ...

  8. 面试官:讲讲Bean的加载过程

    spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...

  9. 知乎高赞:如果你是一个 Java 面试官,你会问哪些问题....

    注:本文内容选自公众号<Java面试题精选>,内容比较丰富,帮助大家做面试前的准备,可以省不少时间.欢迎收藏点赞,也欢迎去围观原号主! 不断收集整理,汇总网上面试知识点,方便面试前刷题,希 ...

最新文章

  1. 谷歌被指骗取人脸数据:部分获取方法可疑
  2. 中断底半部:softirq、tasklet、workqueue
  3. 使用JDK 13查看TLS配置
  4. 40种Javascript中常用的使用小技巧【转】
  5. 最新版的SSM框架spring5.0搭建教程(附源码)
  6. 蔚来否认关闭硅谷办公室 近期也没有回科创板的计划
  7. python地址多少位_Python获取IP地址对应的地理位置信息!
  8. [vb]On Error GoTo 0和On Error resume区别
  9. 企业信息化投入中咨询服务_嘉萱企业管理咨询服务 让发展中的企业真正实现全面性效益增长...
  10. windows apache 负载均衡配置 Tomcat集群配置
  11. Eclipse调试时Application XXX is waiting for the debugger to attach的提示
  12. yaml 标记语言说明
  13. oracle学习笔记之pI/sql视频小结
  14. C的xml编程-libxml2(转)
  15. SpringBoot结合ActiveMQ(同时支持Queue和Topic)
  16. 【内部流出,勿做商用】今日教大家如何抢聚划算
  17. LTE CQI/PMI 上报机制
  18. MapReduce算法(将数据按照 /OutputData/城市名称/日期(YYYY-MM-dd)/类型(固定Gn)/imsi.txt )
  19. python 计算list中平均值_python里的list求平均值
  20. Svn主分支次分支合并和版本回退

热门文章

  1. html两个div浮动后下一个div怎么换行的问题
  2. 测试敏捷化 vs 敏捷测试
  3. 教育部:原则上疫情得到有效控制前,大学生不返校、高校不开学
  4. [Errno 13] Permission denied: ‘/home/robot/catkin_ws/build‘
  5. 如何在win 10 家庭版上安装日语语言包
  6. Mysql 左连接 多个字段
  7. CSS3 Generator在线工具
  8. 51单片机_动态数码管显示
  9. C# 键盘响应事件及键值对照表
  10. 基于VB6.0的货架数量管理系统