对java内部类的理解

常规内部类可以访问外部类的方法或变量。常规内部类所在的类不能直接访问内部类的非静态成员或方法,只有先生成一个内部类的实例,然后在访问该实例的变量或方法(private的也可以直接方法,因为private的修饰符允许来自同一个类的访问)。常规内部类总是依附于一个具体的外部类对象,常规内部类实际上维护一个指向其所依附的外部类对象的一个引用。当常规内部类的对象要访问外部类对象的变量或方法时,会向外部类对象发送消息。常规内部类需要访问的外部类变量由对应的外部类对象来保存,这些变量随时可以通过引用找到外部类对象,从而取出。而对于局部内部类来说,假设他需要访问所在方法中的局部变量,由于该局部变量在方法退出时就会被释放掉,因此局部内部类需要自己在保存该局部变量的副本(实际上编译器会给局部内部类添加一个成员变量用于保存该局部变量的副本)。如果局部内部类所在的方法的局部变量不是final,该变量在方法中随时会被改变,而局部内部类在构造时时成员变量就已经被初始化了(不可能和外部局部变量随时同步),因此可能出现局部内部类保存的其所在方法的局部变量的副本和该方法的局部变量不一致的情况。为了避免这种不一致情况,强制要求局部内部类所引用的所在方法的局部变量必须为final的。可以这样认为,由于常规内部类随时获取通过其所依附的外部类对象的当前成员变量的值,因此这种变量访问是同步的;而匿名内部类需要访问的其所在方法的局部变量没有固定的对象来保存(方法运行完后就会十分),所以必须在局部内部类中自己保存(通过编译期添加成员变量的方式),当实际需要时会访问自己保存的副本,这就存在要求副本和原始值保持一致,一旦局部内部类所在的方法改变了该局部变量,局部内部类已经生产的实例是无法感知这种变化的,仍旧会访问自己保存的过时的副本,会造成程序的不可控,因此局部内部类如果要访问其所在方法的局部变量,则强制要求改局部变量时final的。对于静态内部类(只有内部类可以被static修饰),可以直接访问外部类的静态方法或成员,外部类也可以直接访问其所有的静态成员和方法。

 

posted on 2013-12-21 21:42  优雅的码农  阅读(319)  评论(0)    收藏  举报

导航