局部内部类为什么只能访问final局部变量,对于成员变量却可以随便访问?
局部内部类为什么只能访问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局部变量,对于成员变量却可以随便访问?的更多相关文章
- 类变量方法,局部变量和成员变量的区别(this关键字的使用)
变量名首写字母使用小写,如果由多个单词组成,从第2个单词开始的其他单词的首写字母使用大写. 如果局部变量的名字和成员变量的名字相同, 要想在该方法中使用成员变量,必须使用关键字this class P ...
- java基础学习总结三(jdk7新特性、变量(局部变量和成员变量)、常量以及运算符)
一:jdk7新特性 可以表示二进制数值,以0b开头,中间可以使用下划线_分隔符.如下: @Test /** * 测试jdk新特性 */ public void testJdk7(){ int a=0b ...
- C#面向过程之局部变量、成员变量、变量作用域、可变参数
局部变量与成员变量: 局部变量:定义在方法里面的变量就叫做局部变量:没有默认的初始值,使用变量之前必须给它赋值成员变量:定义在类下面的变量叫做成员变量:如果是数值类型默认初始值为0 如果是引用类型默 ...
- java利用反射绕过私有检查机制实行对private、protected成员变量或方法的访问
在java中,如果类里面的变量是声明了private的,那么只能在被类中访问,外界不能调用,如果是protected类型的,只能在子类或本包中调用,俗话说没有不透风的墙.但是可以利用java中的反射从 ...
- java的局部变量和成员变量以及区别
一.局部变量 存在某个方法中的变量就叫局部变量,局部变量一旦声明就必须赋值 否则不能使用 代码如下: class Person { String name; char sex; int age; pu ...
- Java反射机制可以动态修改实例中final修饰的成员变量吗?
问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...
- java类(Class)的概念;对象的概念,声明类的属性 和方法,局部变量和成员变量,面向对象编程思维,抽象的概念
类(Class)的概念 类是对一组具有相同特征和行为的对象的抽象描述. 理解: [1] 类包含了两个要素:特性和行为 => 同一类事物具有相同的特征和行为. [2] 类是一个群体性概念.例如:网 ...
- 类中被final修饰的成员变量需要初始化
类中被final修饰的成员变量需要初始化,否则编译不通过,因为final修饰后不能再赋值,因此必须初始化.
- JAVA中局部变量 和 成员变量有哪些区别
JAVA中局部变量 和 成员变量有哪些区别 1.定义的位置不一样<重点>***局部变量:在方法的内部成员变量:在方法的外部,直接写在类当中 2.作用范围不一样<重点>***局部 ...
随机推荐
- hadoop快照管理
快照相当于对目录做备份,并不会复制所有文件,而是记录文件的变化命令用法 ()hdfs dfsadmin -allowSnapshot 路径 (开启指定目录的快照功能) ()hdfs dfsadmin ...
- c#读取并异步写入文件,简单版,指定编码,保持原格式。
1.同步读取和写入 StreamReader objReader = new StreamReader("E://workspace//zzz//read.txt", Encodi ...
- Classpath in jar关于java加载第三方jar的集中方法和详细解释。
转载地址:http://www.iteye.com/topic/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个ja ...
- python环境变量配置 - CSDN博客
一.下载: 1.官网下载python3.0系列(https://www.python.org/) 2.下载后图标为: 二.安装: Window下: 1.安装路径: 默认安装路径:C:\python35 ...
- Astyle 快速入门,常用指令
--style=java -n -p -c !E astyle是一个命令行工具,命令语法很简单: astyle [options] < original > Beauti ...
- day 57 Django基础五之django模型层之关联管理器
Django基础五之django模型层之关联管理器 class RelatedManager "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器.它存在于下面两种情况 ...
- 第十四篇:PL/SQL Developer Oracle配置和必知基础
1.一般在本地使用PL/SQL 第三方工具操作Oracle数据库,首先你的机器上得有oracle的客户端client,下一个就行了,很小2.首先找到你下载的oracle的客户端的包,找到tnsname ...
- Java学习之继承关系内存分配
假设有C继承B,B继承A; 继承会继承除private修饰的成员变量,方法.但不会继承构造器. 所以调用被继承下来的方法时,不需要指明主调者,但是调用构造器时,就需要指明主调者,那就是super.如果 ...
- Hamilton回路 旅行商TSP问题 /// dp oj1964
题目大意: 给出一个n个顶点的无向图,请寻找一条从顶点0出发,遍历其余顶点一次且仅一次.最后回到顶点0的回路——即Hamilton回路. Input 多测试用例.每个测试用例: 第一行,两个正整数 n ...
- mac os Catalina beta Jetbrains idea闪退解决方案
第一时间升级最新版本的Catalina 10.15 Beta 版(19A501i) 后, 发现不管在idea 输入什么,都会直接crash. 不论是卸载重装还是,clean,结果都是一样的. 在网上查 ...