内部类主要分为4种:静态内部类、成员内部类、局部内部类、匿名内部类
- 静态内部类
是指被声明为static的内部类,它可以不依赖于外部类实例而被实例化,而通常的内部类需要在外部类实例化后才能实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法(包括私有类型)。
- 成员内部类
可以自由地引用外部类的属性和方法,无论是不是静态的。但它与一个实例绑定在了一起,不可以定义静态属性和静态方法。只有在外部类被实例化后,这个内部类才能被实例化。注意,非静态内部类中不能有静态成员。
- 局部内部类
局部内部类像局部变量一样,不能被public、protected、private以及static修饰,只能访问方法中定义为final类型的局部变量。
- 匿名内部类
使用时,牢记以下几个原则:
- 不能有构造函数
- 不能定义静态成员、方法和类
- 不能是public、protected、private和static
- 只能创建匿名内部类的一个实例
- 一个匿名内部类一定是在new的后面,这个匿名类必须继承一个父类或实现一个接口
- 因为匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效(例如,只能访问方法中定义为final类的局部变量)
面试:局部内部类要使用局部变量,为什么这个局部变量必须是final的?
(第一次面试被问到这个问题,当时就懵逼了。。。。。。结束后立刻查找资料,得出以下结论)
所谓“局部内部类”就是在对象的方法成员内部定义的类,而方法中的类,访问同一个方法中的局部变量是天经地义的,为什么一定要加final呢?
原因就是,内部类对象的生命周期往往会超过局部变量的生命周期。Why?如果局部变量没有加final,那么这个局部标量就是在Java栈中被创建的,当方法结束时退栈,此时,这些局部变量全部死亡。但是,内部类对象生命周期与其它类一样,当创建一个该局部类对象后,只有当没有其它人再引用它时,它才会死亡。也就是说,一个方法已调用结束(局部变量已死亡),但局部内部类的对象仍然存活。即,局部类的生命周期会超过局部变量。所以,这种情况是不合理的。也就是说,局部变量的生命周期要大于等于局部内部类的生命周期,即,这个局部变量必须加final。