局部内部类为什么只能访问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. lxhgww的奇思妙想 长链剖分板子

    https://vijos.org/d/Bashu_OIers/p/5a79a3e1d3d8a103be7e2b81 求k级祖先,预处理nlogn,查询o1 //#pragma GCC optimiz ...

  2. Myeclipse从外部导入项目时,jsp和html页面中所有的onclick="return xx()"位置均出现cannot return from outside function() or method()错误

  3. 第一个servlet小程序

    第一个servlet小程序 com.fry.servlet.HelloServlet package com.fry.servlet; import javax.servlet.ServletExce ...

  4. Java-Maven-pom.xml-porject-parent:parent

    ylbtech-Java-Maven-pom.xml-porject-parent:parent 1.返回顶部 1.Inherit defaults from Spring Boot <!-- ...

  5. System.String.cs

    ylbtech-System.String.cs 1.程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c5619 ...

  6. NPM 使用介绍(包管理工具,解决NodeJS代码部署上的很多问题)

    引用地址:http://www.runoob.com/nodejs/nodejs-npm.html NPM 使用介绍 NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问 ...

  7. day 73 Django基础八之cookie和session

      Django基础八之cookie和session   本节目录 一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session 六 x ...

  8. python+appium真机运行登录例子

    一.手机USB连接电脑(手机打开调试模式) 验证:cmd -> 输入adb devices,查看手机的UDID.显示如下表示 连接成功 二.启动Appium服务 1. 启动Appium,点击 右 ...

  9. <Python基础>装饰器的基本原理

    1.装饰器 所谓装饰器一般是对已经使用(上线)的函数增加功能. 但是因为一般的大公司的严格按照开放封闭原则(对扩展是开放的,对修改是封闭的),不会让你修改原本的函数. 装饰器就是在不改变原本的函数且不 ...

  10. BCD Code ZOJ - 3494 AC自动机+数位DP

    题意: 问A到B之间的所有整数,转换成BCD Code后, 有多少个不包含属于给定病毒串集合的子串,A,B <=10^200,病毒串总长度<= 2000. BCD码这个在数字电路课上讲了, ...