黑马程序员技术交流社区
标题:
【技术问题】方法中的内部类能访问方法中的局部变量吗?
[打印本页]
作者:
蓝墨清幽
时间:
2015-4-22 13:28
标题:
【技术问题】方法中的内部类能访问方法中的局部变量吗?
方法中的内部类能不能访问方法中的局部变量,为什么?
希望有代码例子
作者:
itheima_llt
时间:
2015-4-22 14:16
祝楼主快乐,大家一齐讨论!
作者:
itheima_llt
时间:
2015-4-22 15:47
完全支持你,大家都会顶你
作者:
itheima_llt
时间:
2015-4-23 13:39
内部类的生命周期和方法中的局部变量是不一样的,内部类是也是一个类,是存储在堆中,也只有当对该类的引用消失时,内部类才会消亡。而方法的局部变量是存储在堆栈中的,当调用结束时就会退栈,即在内存中这个属性就消失了。也就是说,内部类的生命周期超过了方法中局部变量的生命周期,内部类可能会调用到已经消失的属性,因此内部类不能访问方法中的局部变量。
解决方法就是在局部变量前加修饰符final
,此时局部变量就会存在堆中,生命周期跟工程的生命周期是一样的,此时内部类就可以访问方法中的局部变量。
作者:
itheima_llt
时间:
2015-4-23 13:42
/*
内部类定义在局部时,
1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
*/
class Outer
{
int x = 3;
void method(final int a)
{
final int y = 4;
class Inner
{
void function()
{
System.out.println(y);
}
}
new Inner().function();
}
}
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method(7);
out.method(8);
}
}
复制代码
作者:
itheima_llt
时间:
2015-4-23 13:44
如果上面的无法理解,回过头来找到关于堆栈示意图的知识,好好复习一下,自己画画图。
作者:
WYKings
时间:
2015-4-23 13:44
楼上给出了正解,我就不多说什么了
就是那么一点:类存储空间在堆内存空间,而方法中的变量存储在栈内存空间,如果类去访问方法中已经被释放了的变量,所以不能直接访问
方法中的变量加上final修饰符后,也存储在堆内存空间,就可以访问了
作者:
waylent
时间:
2015-4-23 14:07
不能,因为方法中的内部类的生命周期可能比方法中的局部变量的生命周期要长。
内部类存储在堆内存中,只有当对内部类的全部引用消失时,内部类才会被垃圾回收。
而方法中的局部变量存储在栈内存当中该方法的栈帧中,当该方法执行完毕,栈帧会弹出,局部变量也会跟着消失。
如果在方法执行完毕后,方法中的内部类还能被其他地方引用,
那么方法中的内部类的生命周期就会比方法中的局部变量要长,此时局部变量已经消失,当然就更不可能访问到。
如果局部变量被final修饰,方法中的内部类就能访问这个局部变量了。
下面的代码演示方法中的内部类的生命周期比方法中的局部变量长的情况:
当代码执行到主函数的第二行,调用show方法执行完毕后,show方法中x变量已经在内存中消失。
而此时内部类Inner的引用inner仍然保留,仍然能调用print方法,如果print方法能访问x,此时将产生不可预知的结果。
interface InnerInterface{
public void print();
}
//外部类
class Outer{
Object inner;
//外部类成员方法
public InnerInterface show(){
//方法中的局部变量
int x=2;
final int y=3;
//方法中的内部类
class Inner implements InnerInterface{
// int z=x;//方法中的内部类的成员变量也不能访问方法中的局部变量,否则编译报错
public void print(){
// System.out.println(x);//方法中的内部类的成员函数中,也不能访问方法中的局部变量,否则编译报错
System.out.println("y="+y);//可以访问被final修饰的变量
}
}
return new Inner();
}
}
public class Test1 {
public static void main(String[] args){
//调用show方法,执行完毕后,show方法中x变量已经在内存中消失
InnerInterface inner= new Outer().show();
//而此时内部类Inner的引用inner仍然保留,仍然能调用print方法
inner.print();
}
}
复制代码
作者:
Freshbird
时间:
2015-4-23 16:09
看着代码太多了,解释那么麻烦?
作者:
Taekwon-boy
时间:
2015-4-23 18:17
局部变量加final修饰可以
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2