A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

能不能给我举一个说明下,谢谢

9 个回复

倒序浏览
wosika 来自手机 中级黑马 2016-9-11 17:19:27
沙发
因为类是加载到方法区中。而局部变量是随意方法的进栈而产生,随着方法的弹栈而消失,所以在局部内部类访问局部变量时,要给局部变量给final修饰使其变成常量,进入常量池,生命周期变长。
回复 使用道具 举报
内部类的生命周期和方法中的局部变量是不一样的,内部类是也是一个类,是存储在堆中,也只有当对该类的引用消失时,内部类才会消亡。
*        而方法的局部变量是存储在堆栈中的,当调用结束时就会弹栈,就是在内存中这个属性就消失了。
*        内部类的生命周期超过了方法中局部变量的生命周期,内部类可能会调用到已经消失的属性,因此内部类不能直接访问方法中的局部变量。
* 解决方法:局部变量前加修饰符final,此时局部变量就会存在堆中,生命周期和内部类的生命周期是一样的,此时内部类就可以访问方法中的局部变量。
如以下代码中 局部变量 num就要被 final修饰.  jdk1.8可以不需要写final修饰,不过会系统会默认添加final修饰
    class Outer {
        public void method() {
                final int num = 10;
                class Inner {
                        public void print() {
                                System.out.println(num);
                        }
                }

                Inner i = new Inner();
                i.print();
        }
回复 使用道具 举报
内部类  可以当作是整个类的一个方法 ,,,, 当方法被调用的时候,, , 他会在堆内存中创建一个对象,,,,,,局部变量是在栈内存中的, , , 不在一个地方 ,,,生命周期也不一样,, ,, , 就像 我来了  你刚走 , ,, , 会出现这种访问不到的错误 , ,  所以  把局部变量用final  修饰  ,,, , 修饰之后, , , 他就变成了 常量 , , ,在方法区的静态常量池里,   在类加载的 时候, ,  他就存在了,,,,,而且  被类中的所有对象所共享,,,,内部类也可以看作是外部类的一个对象,,,,,,  这样的话 , , ,, ,就可以访问,,,,而不会报错了

点评

小伙可以 直接一句话完事, 延长该局部变量的生命周期  发表于 2016-9-11 21:05
回复 使用道具 举报
在方法中创建内部匿名类时,一般是作为callback接口的实现而创建的,可能方法已经执行完了局部变量生命周期结束了,之后如果callback触发了,就可能引起变量引用丢失等内存访问不一致。
而加上final后,编译器是这样处理内部类的。如果这个外部局部变量是常量,则在内部类代码中直接用这个常量。如果是类的实例,则编译器将产生一个内部类的构造参数,将这个final变量传到内部类里,这样即使外部局部变量无效了,还可以使用。
内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。
这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内部类改掉了这些参数的值也不可能影响到原参 数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他们是同一个东西,如果编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时 候又发现值其实没有被改掉,这就让人非常的难以理解和接受,为了避免这种尴尬的问题存在,所以编译器设计人员把内部类能够使用的参数设定为必须是 final来规避这种莫名其妙错误的存在。
回复 使用道具 举报
总的来说就是一句话,延长变量的生命周期
回复 使用道具 举报
主要就是他们的生命周期不同造成的
回复 使用道具 举报
方法加载进栈,当方法弹栈,方法内的变量,也会消失,当内部类访问的方法的局部变量时,而此时该方法应弹栈,程序将无法运行。如果用final修饰数据就会被加载到常量池中,内部类随时可以访问。一句话就是为了延长变量的生命周期。
回复 使用道具 举报
又多了一点知识
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马