局部内部类为什么只能访问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. csp-s模拟100,101T1,T2题解

    题面:https://www.cnblogs.com/Juve/articles/11799325.html 我太蒻了只会T1T2 组合: 欧拉路板子?不会呀... 然后打了个优化,防止暴栈 #inc ...

  2. 解决Delphi 2010启动时卡死并报displayNotification堆栈溢出错误

    1. 清理IE的历史记录,删除浏览器缓存(不需要清cookie) 2. 禁用startpage 2.1 从 Delphi 2010 启动菜单上点右键 -> 查看属性->快捷方式->目 ...

  3. exit与return的区别

    ===========================PHP的解释=========================================================== return ...

  4. VS2010-MFC(常用控件:列表视图控件List Control 上)

    转自:http://www.jizhuomi.com/software/195.html      列表视图控件简介 列表视图控件List Control同样比较常见,它能够把任何字符串内容以列表的方 ...

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

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

  6. PHP面向对象魔术方法之__call函数

    l 基本介绍: (1) 当我们调了一个不可以访问的成员方法时,__call魔术方法就会被调用. (2) 不可以访问的成员方法的是指(1. 该成员方法不存在, 2. 成员方法是protected或者 p ...

  7. Google Chrome浏览器安装xpath helper插件

    1. 图中桌面的两个2.0.2_0文件就是xpath helper插件. --------------------------------------------------------------- ...

  8. Stern-Brocot Tree、伪.GCD 副本

    Stern-Brocot Tree.伪.GCD 副本 伪.GCD 问题 1:\(f(a,b,c,n) = \sum_{i=0}^{n} [\frac{ai+b}{c}]\) Case 1: \(a\g ...

  9. task code

    using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks ...

  10. C++模拟实现Objective-C动态类型(附源码)

    在OC(Objective-C)里面有动态类型分为以下几类: -(BOOL)isKindOfClass:classObj 是否是classObj类或其子类 -(BOOL)isMemberOfClass ...