黑马程序员技术交流社区
标题: 提问为什么在局部位置上的内部类访问局部变量,此局部... [打印本页]
作者: 张志民 时间: 2014-5-16 21:04
标题: 提问为什么在局部位置上的内部类访问局部变量,此局部...
本帖最后由 张志民 于 2014-5-17 19:25 编辑
提问为什么在局部位置上的内部类访问局部变量,此局部变量就必须加final?,我忘了,勿喷
作者: 张百振 时间: 2014-5-16 21:47
首先给你简单介绍一下java基础中的数据类型,
简单数据类型
在Java语言中,简单(或基本)数据类型分了以下八种: 字节型(byte)、短整型(short)、整型(int)、长整型(long)、字符型(char)、浮点型
(float)、双精度型(double)、布尔型(boolean)
在这些当中,又可以分为四组:
1、整数:该组包括字节型(byte)、短整型(short)、整型(int)、长整型(long)、它们有符
号整数。
2、浮点型数:该组包括浮点型(float)、双精度型(double)、它们代表有小数精度要求的数字。
3、字符:这个组包括字符型(char),它代表字符集的符号,例如字母和数字。
4、布尔型:这个组包括布尔型(boolean),它是一种特殊的类型,表示真(true)/假(false)值
引用数据类型
除了这四类八种剩下的都是引用数据类型
再给你说一下栈内存的堆内存
栈内存
上面所说的基本数据类型的局部变量都是在栈内存中定义的,栈内存有一个特点就是,当这个基本数据已经不再它的作用范围的时候,这个数据就会被立刻清除掉,意思就是当基本数据类型不在它的作用域而成为垃圾的时候,系统会立刻将这个数据清除,以释放内存.
堆内存
引用类型的数据和成员变量都是存储在堆内存中的,堆内存有一个特点,就是当这个引用类型的数据成为垃圾的时候,系统不会立刻将其清除掉,而是在系统的内存即将不够用的时候再开始清理所有的堆内存中的垃圾.
现在重点来了,你说的局部变量是在栈内存中的,当出了这个局部变量的作用范围就不能够被访问,先看以下代码
class Outer{
int a = 10;
public void show{
int b = 20;
}
Class Inner{
int c = 30;
public void show1{
System.out.println(a);
}
}
}
现在有一个Outer类,然后在他里边定义了一个局部内部类,a是外部类的成员变量,所以它在堆内存中,只有当这个类的实例被JVM当做垃圾回收的时候这个成员变量a才会消失,然而,b是一个局部变量,b的作用范围就是在定义它的代码块中,也就是出了这个定义它的代码块,这个b就会消失,它并不是和这个类的实例的寿命一样长的
简洁的说a的寿命是和这个对象一样长,而b的寿命很短,出了它的有效范围就消失.
所以说你在内部类的show方法里边是访问不到局部变量b的.
再看下面代码
class Outer{
int a = 10;
public void show{
final int b = 20;
}
Class Inner{
int c = 30;
public void show1{
System.out.println(b);
}
}
}
现在我将外部类的局部变量b改成final的,final是最终的意思,当修饰变量的时候,这个变量只能被赋值一次,不能再改变,相应的,当final修饰局部变量,这个局部变量的寿命也就延长了,就在这个类的消失而消失,
所以现在在内部类里边可以访问到这个变量b,因为它的寿命延长到和成员变量一样,在别的地方也能够防伪标到,也就不受局部变量这个作用域的限制.
如果强制在内部类的局部位置访问外部类的局部变量,会出现报错,这是因为当外部类的局部成员不是final的时候,你这个方法是一直在访问着b的,而你这个方法的寿命是和类一样,所以说在类成为垃圾消失之前这段时间里,你的方法一直在访问局部变量b,而这个时候b已经在栈内存中消失了,所以你的方法会找不到这个变量b,所以报错
希望可以帮你解决问题
这是四类八种简单数据类型,他们有一个共性的特点,就是他们在Java中被定义的时候
作者: 蛤蟆太康 时间: 2014-5-16 23:27
简单来说,局部变量是存在栈中的,类是存在堆中的,栈中的数据用完就是垃圾了,当内部类想调用局部变量的时候,它已经不存在了,所以为了延长局部变量的寿命,必须加上final,这样就不会当做垃圾处理了,只有这样内部类才能访问局部变量。
作者: 郭帅帅 时间: 2014-5-16 23:48
加final是为了把这个变量变成全局变量,可以理解为覆盖面变大,然后其他变量就能访问它了
作者: ID1003 时间: 2014-5-16 23:56
在匿名内部类中,局部变量存在于栈内存中,当变量不加final的时候,通过调用之后,就会被JVM默认为垃圾,所以再后面调用的时候会被认为已经没有这个变量,说的通俗一点就是他的保质期过了,所以不能用了,当加了final之后,就变成了一个常量,可以随时被调用了。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |