【176期】面試官:你知道為什么要加 final 關(guān)鍵字了嗎?
閱讀本文大概需要 2.8 分鐘。
來自:www.jianshu.com/p/acc8d9a67d0c
現(xiàn)象描述

但是在 Java 8 之后,類似場景卻沒有再提示了:

難道是此類變量可以隨便改動(dòng)了嗎?當(dāng)然不是,當(dāng)你試圖修改這些變量的時(shí)候,仍然會(huì)提示錯(cuò)誤:

可以看到,當(dāng)試圖修改基本數(shù)據(jù)類型的變量時(shí),編譯器的警告變成了“Varible 'num' is accessed from within inner class, need to be final or effectively final”,很遺憾,仍然不能修改。相比之下,Kotlin 是沒有這個(gè)限制的:

原因分析

不難推斷,這個(gè) TestInnerClass$1.class 就是匿名內(nèi)部類編譯后的文件,看看它反編譯后是什么內(nèi)容:
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);
}
}
情景對比
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);
<undefinedtype> 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);
}
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);
}
推薦閱讀:
【175期】面試官:談?wù)凪ySQL是如何解決幻讀問題的?
【174期】華為OD(外包)社招技術(shù)二面,總結(jié)復(fù)盤
【173期】面試官:說說單點(diǎn)登錄的三種實(shí)現(xiàn)方式
微信掃描二維碼,關(guān)注我的公眾號
朕已閱 

