局部内部类为什么只能访问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局部变量,对于成员变量却可以随便访问?的更多相关文章

  1. 类变量方法,局部变量和成员变量的区别(this关键字的使用)

    变量名首写字母使用小写,如果由多个单词组成,从第2个单词开始的其他单词的首写字母使用大写. 如果局部变量的名字和成员变量的名字相同, 要想在该方法中使用成员变量,必须使用关键字this class P ...

  2. java基础学习总结三(jdk7新特性、变量(局部变量和成员变量)、常量以及运算符)

    一:jdk7新特性 可以表示二进制数值,以0b开头,中间可以使用下划线_分隔符.如下: @Test /** * 测试jdk新特性 */ public void testJdk7(){ int a=0b ...

  3. C#面向过程之局部变量、成员变量、变量作用域、可变参数

    局部变量与成员变量:  局部变量:定义在方法里面的变量就叫做局部变量:没有默认的初始值,使用变量之前必须给它赋值成员变量:定义在类下面的变量叫做成员变量:如果是数值类型默认初始值为0 如果是引用类型默 ...

  4. java利用反射绕过私有检查机制实行对private、protected成员变量或方法的访问

    在java中,如果类里面的变量是声明了private的,那么只能在被类中访问,外界不能调用,如果是protected类型的,只能在子类或本包中调用,俗话说没有不透风的墙.但是可以利用java中的反射从 ...

  5. java的局部变量和成员变量以及区别

    一.局部变量 存在某个方法中的变量就叫局部变量,局部变量一旦声明就必须赋值 否则不能使用 代码如下: class Person { String name; char sex; int age; pu ...

  6. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  7. java类(Class)的概念;对象的概念,声明类的属性 和方法,局部变量和成员变量,面向对象编程思维,抽象的概念

    类(Class)的概念 类是对一组具有相同特征和行为的对象的抽象描述. 理解: [1] 类包含了两个要素:特性和行为 => 同一类事物具有相同的特征和行为. [2] 类是一个群体性概念.例如:网 ...

  8. 类中被final修饰的成员变量需要初始化

    类中被final修饰的成员变量需要初始化,否则编译不通过,因为final修饰后不能再赋值,因此必须初始化.

  9. JAVA中局部变量 和 成员变量有哪些区别

    JAVA中局部变量 和 成员变量有哪些区别 1.定义的位置不一样<重点>***局部变量:在方法的内部成员变量:在方法的外部,直接写在类当中 2.作用范围不一样<重点>***局部 ...

随机推荐

  1. 出现不不能引java.util.Date包的情况

    出现不不能引java.util.Date包的情况 那个时间段不能引,IDE的bug,等一会儿就好了 心得:很多时候没必要和bug死磕,因为真的不是你的问题.

  2. 搞大数据,你不懂这三大数据处理趋势就OUT了

    搞大数据,你不懂这三大数据处理趋势就OUT了 企业数据每年以PB级甚至上百PB爆炸式增长,越来越大的数据量正为扩大分析策略在企业应用软件领域的拓展提供了数据基础,但数据的价值是有时效性的,越早分析越能 ...

  3. os.path.dirname(__file__)使用、Python os.path.abspath(__file__)使用

    python中的os.path.dirname(__file__)的使用 - CSDN博客https://blog.csdn.net/u011760056/article/details/469698 ...

  4. Pycharm中如何加载多个项目同时存在

    原文地址: http://www.cnblogs.com/mrgavin/p/6382406.html 今天在使用Pycharm工具练习Python时遇到一个疑问:在已存有项目A工程的前提下如何新建另 ...

  5. PAT甲级——A1119 Pre- and Post-order Traversals【30】

    Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can ...

  6. mint-ui loadmore 上拉加载的坑

    <div style="height:100vh;overflow: scroll;"> <mt-loadmore :top-method="loadT ...

  7. 01_springboot2.x之springboot入门

    1.简介 Spring Boot来简化Spring应用开发,约定大于配置, 去繁从简,just run就能创建一个独立的,产品级别的应用. 优点: 1.简化Spring应用开发的一个框架: 2.整个S ...

  8. LINQ用法总结

    之前一直用sql和拉姆达表达式,一直感觉linq不好用.用熟练了感觉期功能好强大,查询性能例外考究.这里讲讲基本用法. 内联查询: var list2 = (from a in db.Role whe ...

  9. php socket模拟http中post或get提交数据

    php socket模拟http中post或者get提交数据的示例代码. 代码: sock_post.php: <?php /** * php socket模拟post\get请求 * 编辑:脚 ...

  10. T2963 贪吃蛇【BFS,四进制状压,A*】

    Online Judge:未知 Label:BFS,四进制状压,暴力,A*,哈希,玄学. 题目描述 给定一个n*m的地图和蛇的初始位置,地图中有些位置有石头,蛇不能经过.当然蛇也不能爬到地图之外. 每 ...