黑马程序员技术交流社区

标题: 关于java里方法的内部类只能访问被final修饰的局部变量和... [打印本页]

作者: 晓风    时间: 2014-8-11 22:17
标题: 关于java里方法的内部类只能访问被final修饰的局部变量和...
本帖最后由 晓风 于 2014-8-12 09:27 编辑

之前看视频的时候也有疑问,自己虽然知道个中原因,但确不能够很好的说明。
后来在论坛里也有同学提问过,看过了回复。可还不是很明了。自己也查了资料。
以下是自己综合各方面的一些总结:
在java中, 方法的内部类可以访问方法中的局部变量,但必须用final修饰才能访问。
原因:
   一, 当方法被调用运行完毕之后,局部变量就已消亡了。但内部类对象可能还存在,
           直到没有被引用时才会消亡。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量。
                        
   二,解决这一问题的办法就是使用final修饰局部变量,通过将final局部变量"复制"一份,
         复制品直接作为方法内部类中的数据成员,这事方法内部类访问的其实是这个局部变量的复制品!
         而且,由于被final修饰的变量赋值后不能再修改,所以就保证了复制品与原始变量的一致。
                        
    三,原因二的功能能实现的原因是:Java采用了一种copy   local   variable(复制局部变量)的方式来实现,
            也就是说把定义为final的局部变量拷贝过来用,而引用的也可以拿过来用,只是不能重新赋值。
            从而造成了可以access   local   variable(访问局部变量)的假象,而这个时候由于不能重新赋值,
             所以一般不会造成不可预料的事情发生。
                        
     四, 使用final修饰符不仅会保持对象的引用不会改变,
            而且编译器还会持续维护这个对象在回调方法中的生命周期.
            所以这才是final变量和final参数的根本意义.
作者: sdfe    时间: 2014-8-11 22:26
来看看,学习学习。
作者: そ花痕ゐ蝶梦    时间: 2014-8-11 23:26
受教了!!!
作者: lcycr    时间: 2014-8-12 13:34
又长知识了
作者: 不吃草の牛    时间: 2014-8-13 21:40
不错不错啊。

作者: 桂何钢    时间: 2014-8-13 21:49
楼主总结的不错
作者: Huberry    时间: 2014-8-13 21:52
马上要看这一块
作者: 黑马TYR    时间: 2015-4-13 17:04
不是很清晰
作者: 君子无醉    时间: 2015-6-14 00:54
谢谢 正在查找这部分内容 楼主总结的很详细 只是我想问下 被final修饰的局部变量的生命周期是什么? 比如在main方法中的被final修饰变量  是jvm退出运行后才消失(是不是和static修饰的变量生命周期一样? 随着类的消失而消失?) 还是访问它的局部匿名对象不再使用它的时候消失? 请详细解答下 谢谢
作者: 忧伤-hy    时间: 2015-8-26 17:41
这个问题真的很闹心,在我看来内部内的意义就是在于更方便的访问外部类的成员属性和成员方法,而为何要更进一步声明在方法内,不就是为了访问方法的局部变量吗?然后,好好的变量却变成了final修饰的常量,这就失去了如此设计的初衷
作者: 忧伤-hy    时间: 2015-8-26 17:55
再说了,生命周期的问题,你一个方法内部类只有在方法里创建对象,然后再通过外部类的对象调用方法才能够使用内部类,当方法调用完了,内部类也不可能再被访问到了吧,照理内部类对象也应该成为了垃圾。好像当方法消失后内部类还有作用似得。
必须加final修饰变量,把变量变成常量,延长生命周期的同时也限制了该变量的用途,甚至可以说完全导致变量失去意义,变量不就是因为可以存储不断变化的数据才被声明,就好比人为了长寿,把自己变成石头一样
反正我是很不明白这样设计有什么用处
作者: asinzuo    时间: 2015-8-27 17:07
晓风 发表于 2014-8-11 22:17
之前看视频的时候也有疑问,自己虽然知道个中原因,但确不能够很好的说明。
后来在论坛里也有同学提问过, ...

说的好有道理
作者: 笑笑精灵    时间: 2015-9-10 12:04
正好存在疑问呢。谢谢楼主的讲解
作者: xuehaoran0105    时间: 2015-9-25 21:54
学习学习
作者: lcrobert    时间: 2015-9-28 00:12
没代码说明!!!,差评
作者: ash午夜阳光    时间: 2015-11-1 23:47
第一点中,如何去引用一个已经消亡的方法中的内部类对象?如果没有办法引用的话,这个对象就会在某个时刻被回收,自然,局部变量可以不用定义为final
作者: 283557811    时间: 2015-11-29 10:40
很有用学到知识了
作者: 1066715808    时间: 2016-2-25 17:27
弄懂了点点
作者: 13623544590    时间: 2016-2-26 16:54
都好好努力学习吧
作者: Vintagecheese    时间: 2016-4-22 23:29
不错不错 学习了
作者: sty15193    时间: 2016-5-4 23:12
感谢,受教了
作者: 936994215    时间: 2016-6-13 15:29
不错不错
作者: aA772807986    时间: 2016-11-12 12:31
总结的很全面,厉害!!!
作者: QQ605586042    时间: 2016-12-13 21:00
忧伤-hy 发表于 2015-8-26 17:55
再说了,生命周期的问题,你一个方法内部类只有在方法里创建对象,然后再通过外部类的对象调用方法才能够使 ...

如果考虑到多线程的话你就会好理解了假如类中有如下方法
public void execute() {
                final int a = 10;
                class Desk {
                        public void execute() {
                                new Thread() {
                                        @Override
                                        public void run() {
                                                try {
                                                        Thread.currentThread().sleep(2000);
                                                        System.out.println(a);
                                                } catch (final InterruptedException e) {
                                                        e.printStackTrace();
                                                }
                                        }
                                }.start();
                        }
                }
                new Desk().execute();
                System.out.println("主方法已经over");
        } 在主线程方法执行结束后,内部类里面的方法还在运行
作者: linhaismail    时间: 2017-6-20 00:45
通顺了,多谢




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