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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵永康 中级黑马   /  2012-9-17 19:18  /  1477 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 赵永康 于 2012-9-17 23:54 编辑

我是零基础的,自学的毕老师的视频  现在有个疑惑问问各位大侠。
局部内部类访问器成员为什么要将其定义成final的 ???

5 个回复

倒序浏览
因为局部内部类在源代码编译后也是要生成对应的class文件的(一般会是A$1.class这种形式的文件),那么这个二进制文件是独立于其外围类(A.class)的,就是说它无法知道A类中方法的变量。因此就要求“内部类调用的方法内局部变量必须为final”,这样A$1.class访问A类方法局部变量部分就直接用常量来表示。
回复 使用道具 举报
     应该是变量的作用域的问题,因为匿名内部类是出现在一个方法的内部的,如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final。因为虽然匿名内部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用。

回复 使用道具 举报
在java中,我们访问类中的成员,很多情况下会出现访问规则,就想现实生活中,我们访问朋友一样,先预约等等。
局部内部类在访问其成员的时候,该成员有可能已经执行完毕,在内存中释放。(这时访问是不行的)
所以局部内部类在访问其成员的时候必须保证该成员的存在。因此将该成员定义为final。
被final修饰后,该成员就一直存在,才可以访问。


回复 使用道具 举报
方法中的内部类访问局部变量的时候,局部变量需要被 final 关键字修饰。因为方法中的代码是由上而下顺序执行的,方法运行结束后,局部变量就被销毁,内部类的生命周期可能会比局部变量的生命周期长;看下面的代码,方法中的内部类 调用方法中的局部变量 x ,正常调用的时候内部类能够调用到方法中的局部变量,并将内部类对象 i返回,正常调用结束后,如果方法中的局部变量 x 没有被 final 关键字修饰,x 则会被销毁,我们再通过反射的方式去调用 x 的时候则会发现找不到变量 x ,如果局部变量 x 被 final 关键字修饰后,则 x 在方法运行结束后不会被销毁,而是常驻在内存中直到 JVM 退出,这样再通过反射调用的时候依然可以找到 x 。
回复 使用道具 举报
局部内部类直接访问在其外部定义的对象(包括普通变量),编译器要求参数引用必须是final的。
其中:
1. 必须是局部内部类,显然包括匿名内部类;
2. 内部类访问外部类的对象必须是直接访问。
public class LocalInnerClassUnitTests {   
  
    public void defineInnerClass(final int x) {   
        class MyLocalInnerClass {                           
            public void doSomething() {   
                System.out.println(x);   
            }   
        }   
    }   
}  
public class LocalInnerClassUnitTests {        public void defineInnerClass(final int x) {                class MyLocalInnerClass {                                                public void doSomething() {                                System.out.println(x);                        }                }        }}

像代码中的int x 是本地变量,因为java底层的机制不能存取本地变量,这样导致内部类,没有办法取过来,
所以java直接把本地变量的refrenece拷贝到内部类。

因为这个,所以在编译器里面,加上了一个final,让你不要改变这个值,然你只读不能存,这样感觉就好了
内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,
自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。
    这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内
部类改掉了这些参数的值也不可能影响到原参数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他
们是同一个东西,如果编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时候又发现值其实没有被改掉。
为了避免这种问题,所以编译器设计人员把内部类能够使用的参数设定为必须是final来规避这种莫名其妙错误的存在
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马