局部内部类为什么只能访问final局部变量,对于成员变量却可以随便访问?
public class OuterClass {
private int memberField = 10;
public void outerDo(){
final int localField = fromOther();
class InnerClass{
public void innerDo(){
memberField = localField;
}
};
}
private int fromOther() {
return 20;
}
}
局部变量和成员变量对于内部类而言,具有一定的共性,都是该内部类外面的变量。如果要求内部类只能访问final的局部变量是为了确保局部变量不被修改的话,那么内部类访问成员变量应该也有类似的限制才对
我认为是由于他们的存活范围导致了这个区别:
首先内部类的实例可以在方法结束后依然存活,局部变量在方法结束后却无法存活,所以在内部类中无法访问NON-final的局部变量;
而成员变量的存活时间是取决于外部类的实例的,内部类实例中都会引用当前外部类实例,所以他们拥有一致的生命周期,于是可以访问成员变量。
剩下的问题是,为什么可以访问final的局部变量呢?
如果将一个访问了final的局部变量的内部类进行反编译,可以发现该变量是被作为构造函数的参数传入进去的,与之一起传入的参数还有外部类实例
......
com.study.innerclass.OuterClass$1InnerClass(com.study.innerclass.OuterClass, int);
Code:
Stack=2, Locals=3, Args_size=3
0: aload_0
1: aload_1
2: putfield #12; //Field this$0:Lcom/study/innerclass/OuterClass;
5: aload_0
6: iload_2
7: putfield #14; //Field val$localField:I
10: aload_0
11: invokespecial #16; //Method java/lang/Object."<init>":()V
14: return
LineNumberTable:
line 9: 0
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 this Lcom/study/innerclass/OuterClass$1InnerClass;
既然javac是这样处理内部类的,那么这与为内部类提供一个带参数的构造函数就没什么两样了!
public class OuterClass {
private int memberField = 10;
public void outerDo(){
int localField = fromOther();
class InnerClass{
private int local;
public InnerClass(int local) {
this.local = local;
}
public void innerDo(){
memberField = this.local;
}
};
new InnerClass(localField);
}
private int fromOther() {
return 20;
}
}
分享到:
相关推荐
本文章是关于final部分知识所作的自我总结,内容为final对成员变量和局部变量修饰的简要解答,除了对自我java学习的一个小结,也希望能够帮助到在java路上对该内容疑惑的同行
Java中局部内部类可以访问它所在方法中定义的final修饰的局部变量的合理解释.doc
//从阅读角度,这里预期打印a=20,然而只会打印出a=10,会让人误解,因为在Inner的change()中修改的是Inner内部类对象的this.a,它是m
NULL 博文链接:https://1598623317.iteye.com/blog/2029809
在知乎上看到了一篇帖子 在这个问题下面大家已经吵得不可开交了,看了很多篇文章,被误导进了很多的坑,发现只有下面两篇文章是写的最好的,解释的很清楚,我把两篇文章简单的总结了一下: ...1.问题的引出 ...
012-JavaSE进阶-final修饰局部变量
final修饰变量时,表示该变量一旦获得了初始值之后就不可被改变,final既可修饰成员变量(包括类变量和实例变量),也可以修饰局部变量,形参。 final修饰成员变量 类变量:当类初始化时,系统会为类变量分配内存,...
day11_04_final关键字用于修饰局部变量
在Java中变量可以分为成员变量和局部变量 成员变量 通常每个类中成员变量可以分为 类变量(static修饰的变量) 以及 实例变量 针对这两种类型的变量赋初始值的时机是不同的。 类变量可以再声明变量的时候直接赋...
•内部类提供了更好的封装,内部类成员可以直接访问外部类的私有数据,因为内部类被当成其他外部类成员。 •匿名内部类适合用于创建那些仅需要一次使用的类。 非静态内部类 •定义内部类非常简单,只要...
计算机后端-Java-Java核心基础-第15章 面向对象07 26. final修饰局部变量.avi
一小块区域 成员变量:方法外部,类内部定义的变量 局部变量:类的方法中的变量。 成员变量和局部 变量的区别 作用域 成员变量:针对整个类有效。 局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
4.2.2 final局部变量;4.2.2 final局部变量;4.2.3 final方法;4.2.4 final类;4.2.5 学生实践练习;4.2.5 学生实践练习;4.3 接口;4.3 接口;4.3.1 接口的定义;4.3.2 接口的实现;4.3.2 接口的实现;4.3.2 接口的实现;4.3.2 ...
对于类属性无论通过类还是对象来访问都是访问同一个对象,只要一个对象改变 了类属性,那么其他对象对应的类属性也改变了.成员变量不用显式初始化,只要定义了一个类属性或实例属性,系统 默认进行初始化。 局部变量 ...
B类继承A类,相当于对A类的功能进行扩展,如果不希望对A类进行扩展,可以给A类加final关键字,这样的话,A类就无法继承了。 源代码中String就是没有子孙的 结论:final修饰的类无法被继承 二、final修饰的方法 ...
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。下面就从这三个方面来了解一下final关键字的基本用法。 1.修饰类 当用final修饰一个类时,表明这个类不能被继承。也就是说,...
有趣的事实这个 Android 入门项目演示了用于创建文本字段、按钮、toast、简单 if-else、类用法、数组、onclicklistener、成员变量和局部变量之间的区别与使用“final”声明有关的方法局部变量。 有许多行注释掉的...
240 12.2.1 创建局部内部类 240 12.2.2 在局部内部类中访问外部类成员变量 240 12.2.3 在局部内部类中访问外部类的局部变量 241 12.2.4 静态方法中的局部内部类 243 12.3 静态内部类 244 12.3.1 创建静态内部类 244 ...
1. lambda: 1. 概念:就是对函数式接口匿名内部类的简写 ... 7、lambda表达式若访问了局部变量,则局部变量必须是final的, 若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;
为什么要重载? 168 7.5.3 给汽车加个重载的方法 169 7.5.4 测试一下 169 7.5.5 重载容易引发误解的两个地方——返回类型和形参名 170 7.5.6 重载中的最难点——参数匹配原则 171 7.6 使用类的实例作为方法参数...