黑马程序员技术交流社区

标题: 为什么方法中的内部类不能访问方法中的局部变量 [打印本页]

作者: 马州州    时间: 2012-9-12 23:30
标题: 为什么方法中的内部类不能访问方法中的局部变量
本帖最后由 马州州 于 2012-9-13 00:39 编辑

今天复习到这一点的时候想到这个问题了,我知道方法中的内部类只能访问用final修饰的方法中的局部变量

但是为什么不能访问没有用final修饰的局部变量呢
虽然知道这个是规则,但是还是想了解一下
能不能给解释一下呢

新问题又来了,为什么加了final之后就能访问了呢?
问题无止境,嘿嘿

听了下面同学的解释还有查了一些资料终于明白了
关于为什么必须用final修饰才能调用,是这样解释的

方法中的内部类访问局部变量的时候,局部变量需要被 final 关键字修饰。因为方法中的代码是由上而下顺序执行的,方法运行结束后,局部变量就被销毁,内部类的生命周期可能会比局部变量的生命周期长;看下面的代码,方法中的内部类 调用方法中的局部变量 x ,正常调用的时候内部类能够调用到方法中的局部变量,并将内部类对象 i返回,正常调用结束后,如果方法中的局部变量 x 没有被 final 关键字修饰,x 则会被销毁,我们再通过反射的方式去调用 x 的时候则会发现找不到变量 x ,如果局部变量 x 被 final 关键字修饰后,则 x 在方法运行结束后不会被销毁,而是常驻在内存中直到 JVM 退出,这样再通过反射调用的时候依然可以找到 x 。



看来这些细节的小问题也不能忽视啊
多复习一下之前的知识就会有新发现的问题

作者: 邱成    时间: 2012-9-12 23:41
方法中内部类不能访问该方法的局部变量是因为:

方法中声明内部类,目的只是由外部类来控制内部类的可见性,
将一个类放到一个方法当中去定义的时候,那么就限定了这个类的使用范围只能在方法的内部,

我们只是代码这样写而已,不要理解成为在这个方法内部有一个类,这个类是方法的一部分,
一调这方法类执行什么什么的.. 不是的,

我们只是代码这样写,目的是为了控制内部类的可见性,编译之后的结果,也会出现 外部类 和 内部类
各自的字节码class文件,这就说明内部类是一个独立的个体,他们就是两个类而已,他们各自都有自己
的成员变量和方法。

那么这个在方法中声明的内部类里面当然不能访问该方法的局部变量了,他们就是各自单独的两个类,
你在一个类里面可以通过该类引用访问他的成员变量或者方法,
但是方法中内部声明的局部变量的作用域只是这个方法内部,你无法访问这个局部变量,根本访问不了
举个例子:
//内部类,可以等同的当成一个方法来看待
class Test{
        int i;
        void outMethod(int i){ i = 2;}//一个成员方法,可以直接调用成员属性
        class OutTest{
                void outMethod(){
                        i = 2;                        //所以一个成员内部类也可以直接访问成员属性
                }
        }
        public static void main(String[] args) {
                int j = 2;
                final int k =5;
                class InTest{
                        int inMethod(int j){ return j = j + k;}//final因为是不可变的常量,所以给了特权
                }
                InTest it = new InTest();
                j = it.inMethod(j);//所以同样的,方法内部类也只能传参,不能直接拿到变量
                Test t = new Test();
                t.outMethod(j);//在方法内再调用方法,只能通过传参
        }
}
作者: 李菁    时间: 2012-9-12 23:46
方法中声明内部类,目的是由外部类控制内部类的可见性。
内部类是一个独立的个体,他和外部类属于两个类,他们都有自己的成员变量和方法。
所以在方法中声明的内部类里不能访问该方法的局部变量。
作者: 马州州    时间: 2012-9-12 23:47
本帖最后由 马州州 于 2012-9-12 23:55 编辑
邱成 发表于 2012-9-12 23:41
方法中内部类不能访问该方法的局部变量是因为:

方法中声明内部类,目的只是由外部类来控制内部类的可见 ...


嘿嘿,虽然答案是百度来的,但是我看明白了,为什么加了final之后就能访问了呢
作者: 马州州    时间: 2012-9-12 23:49
李菁 发表于 2012-9-12 23:46
方法中声明内部类,目的是由外部类控制内部类的可见性。
内部类是一个独立的个体,他和外部类属于两个类, ...

正解,看来你对细节掌握的很好啊
作者: 马州州    时间: 2012-9-12 23:55
李菁 发表于 2012-9-12 23:46
方法中声明内部类,目的是由外部类控制内部类的可见性。
内部类是一个独立的个体,他和外部类属于两个类, ...

为什么加了final之后就能访问了呢
作者: 李菁    时间: 2012-9-13 00:08
方法中的变量声明为final的,因为这样可以使变量全局化
局部变量的生命期是当该方法被调用时,方法中的局部变量在栈中被创建;当方法调用结束时,释放栈空间。
内部类对象生命期是和其它类一样,创建一个局部内部类对象后,当没有其它类再引用时,它才释放。
所以局部类的对象生命期会超过局部变量。这样即使栈中的局部变量被释放,但final值是不变的。
作者: 马州州    时间: 2012-9-13 00:18
李菁 发表于 2012-9-13 00:08
方法中的变量声明为final的,因为这样可以使变量全局化
局部变量的生命期是当该方法被调用时,方法中的局部 ...

那方法中的内部类,是什么时候创建的,是怎么创建的。在内存中的哪个位置,
作者: 李菁    时间: 2012-9-13 00:32
这个类用于继承其他类或是实现接口,不需要增加额外的方法,只对继承方法的实现或者覆盖。
这个类只是为了获得一个对象实例,不需要知道它的实际类型。
这个类名没有意义,不需要使用到。
在上边的3中情况下就可以创建匿名内部类
匿名内部类在new后边实现接口即可。
匿名内部类也是属于一个单独的类,你没有new这个类,也就应该还没有分配内存给它

作者: 马州州    时间: 2012-9-13 00:35
李菁 发表于 2012-9-13 00:32
这个类用于继承其他类或是实现接口,不需要增加额外的方法,只对继承方法的实现或者覆盖。
这个类只是为了 ...

对头,我又查了一些资料,终于明白了,谢谢你哈
作者: 李菁    时间: 2012-9-13 00:40
马州州 发表于 2012-9-13 00:35
对头,我又查了一些资料,终于明白了,谢谢你哈

唉 光答题也不给分啊 都没动力啊 怎么也得鼓励鼓励啊
作者: 马州州    时间: 2012-9-13 01:14
李菁 发表于 2012-9-13 00:40
唉 光答题也不给分啊 都没动力啊 怎么也得鼓励鼓励啊

我强烈要求版主给你加分,不给加分我都不愿意啊,这回答的绝对给力,也说明你对这一块儿的确很了解




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2