在开发过程中,由于习惯,我们可能会习惯于某种编程语言的某些特性,尤其是在日常开发中只使用一种语言的情况下。但是当你使用不止一种语言进行开发时,你会发现虽然都是高级语言,但是它们之间的很多特性是不一样的。现象描述在Java8之前,匿名内部类使用外部成员时,会报错提示“Cannotrefertoanon-finalvariablearginsideaninnerclassdefinedinadifferentmethod”:但是在Java8之后,类似scenario却没有更多的提示:莫非这样的变量是可以随意改变的?当然不是,当你试图修改这些变量时,还是会提示错误:可以看到当试图修改基本数据类型的变量时,编译器警告变成了“Varible'num'isaccessedfromwithininnerclass,需要是最终的或有效的最终”,不幸的是,仍然无法修改。相比之下,Kotlin则没有这个限制:原因分析肯定是表面上看不出什么原因,看编译器是怎么做的!运行javac命令后,生成了几个.class文件:不难推断这个TestInnerClass$1.class是匿名内部类的编译文件,看看反编译出来的:原来anonymous也会被处理和普通的Class处理一样,但是编译器在生成它的构造方法时,除了传递外部类的引用外,还会复制基本数据类型的变量,并传递引用数据类型的变量引用。所以,当然不能修改基本数据类型的变量,否则就会和外部变量不一致,这样的话,变量的传递就变得毫无意义了。场景对比但是为什么Kotlin可以在匿名内部类中直接修改一个基本数据类型的值呢?查看Kotlin编译后的反编译内容:可以发现,当需要传递基本数据类型的变量时,Kotlin编译器会将这些数据包裹起来,从而由值传递变为引用传递,这样内部的修改就会当然不影响外面。验证未传递变量时Kotlin编译器如何处理:
