1200页Java架构面试专题及答案
小编整理不易,对这份1200页Java架构面试专题及答案感兴趣劳烦帮忙转发/点赞
百度、字节、美团等大厂常见面试题
可以看到,当试图修改基本数据类型的变量时,编译器的警告变成了 “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);
}
};
完结
Redis基于内存,常用作于缓存的一种技术,并且Redis存储的方式是以key-value的形式。Redis是如今互联网技术架构中,使用最广泛的缓存,在工作中常常会使用到。Redis也是中高级后端工程师技术面试中,面试官最喜欢问的问题之一,因此作为Java开发者,Redis是我们必须要掌握的。
Redis 是 NoSQL 数据库领域的佼佼者,如果你需要了解 Redis 是如何实现高并发、海量数据存储的,那么这份腾讯专家手敲《Redis源码日志笔记》将会是你的最佳选择。
s/4f45ff00ff254613a03fab5e56a57acb)收录**