内部类:
内部类作为其外部类的成员,所有可以使用任何访问控制符(private、default、protected、public)修饰。(外部类不能用private、protected修饰)
1. 成员内部类
不是定义在方法里的内部类
1.1 非静态内部类
1.1.1 在非静态内部类对象里,保存了一个它所寄生的外部类对象的引用
所以:如果外部类成员变量、内部类成员变量与内部类里方法的局部变量同名,则可通过使用this、外部类类名.this作为限定来区分当前内部类对象和外部类对象。
1.1.2 外部类不能直接访问非静态内部类的实例变量
如果外部类需要访问静态内部类的实例成员,则必须显示创建非静态内部类的对象来调用访问其实例成员
1.1.3 不允许在外部类的静态成员中直接使用非静态内部类
外部类的静态方法、静态代码块不能直接访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例等。
1.1.4 不能在非静态内部类里定义静态成员
非静态内部类里不能有静态方法、静态成员变量、静态初始化块。
1.2 静态内部类(类内部类)
1.2.1 静态内部类对象值持有外部类的类引用,没有持有外部类的对象引用
1.2.2 如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。
外部类的上一级程序单元是包,所以不可使用static修饰;而内部类的上一级程序单元是外部类,使用static修饰可以将内部类变成外部类相关,而不是外部类实例相关。
1.2.3 静态内部类可以包含静态成员,也可以包含非静态成员
1.2.4 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员
即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。
1.2.5 因为静态内部类是外部类的一个静态成员,所以外部类的所有方法、所有初始化块中可以使用静态内部类来定义变量、创建对象等
1.2.6 外部类依然不能直接访问静态内部类的成员
但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员;也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。
2. 局部内部类
在方法里定义的内部类
补充:
1. java还允许在接口中定义内部类
接口中定义的内部类默认使用public static修饰,也就是说,接口内部类只能是静态内部类。且访问控制符只能是public。
2. 接口里能定义内部接口
接口里的内部接口是接口的成员,因此系统默认添加public static 修饰符。且访问控制符只能是public。
为什么静态内部类的实例方法也不能访问外部类的实例属性呢?
答:因为静态内部类是外部类的类相关的,而不是外部类的对象相关的。也就是说,静态内部类对象不是寄生在外部类的实例中,而是寄生在外部类的类本身中。当静态内部类对象存在时,并不存在一个被它寄生的外部类对象,静态内部类对象只持有外部类的引用,没有持有外部类对象的引用,如果允许静态内部类的实例方法访问外部类的实例成员,但找不到被寄生的外部类对象,这将引起错误。