随笔:Java内部类小结
内部类
内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员直接可以互相访问。但外部类不能访问内部类的实现细节,例如内部类的成员变量。
内部类与外部类的语法大致相同,但是有两点区别:
- 内部类比外部类可以多使用三个修饰符:private,protected,static
- 非静态内部类不能拥有静态成员。
成员内部类
成员内部类是一种与成员变量、方法、构造器和初始化块相似的类成员,局部内部类和匿名内部类则不是类成员。
成员内部类分为两种:静态内部类和非静态内部类。
非静态内部类
非静态内部类有一个外部类对象的引用,当在非静态内部类的方法中访问某一个变量时,先在这个方法中找,再在内部类中找,最后才在外部类中找。
如果外部类成员变量、内部类成员变量与内部类里的方法的局部变量同名,则可通过使用this,外部类类名.this作为限定来区分。
如果外部类需要访问非静态内部类的成员,则必须显示创建非静态内部类对象来调用访问其实例成员(无论内部类是public还是private修饰,都可以访问任何成员,因为外部类访问非静态内部类对象时,可能还不存在)。
不允许在外部类的静态成员中直接使用非静态内部类。
静态内部类
使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。所以把静态内部类看成类的静态成员。
根据静态成员不能访问非静态成员的规则(因为在访问时,实例对象可能还没有,所以访问不了),静态内部类不能访问外部类的实例成员,只能访问外部类的类成员,即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。
外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。
使用成员内部类
在外部类以外定义和创建非静态内部类
Outer.Inner a = null;
a = new Outer().new Inner();
在外部类以外使用静态内部类,因为是外部类相关的,所以无需创建外部类对象
Outer.Inner a = null;
new Outer.Inner();
局部内部类
如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类也不能使用访问控制符和static修饰符修饰。也可以访问外部类的所有成员。
匿名内部类
创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。
new 实现接口() | 父类构造器(实参列表)
{
//实体
}
匿名内部类不能是抽象类,因为会立即创建匿名内部类的对象,不能定义构造器,因为没有类名,但是可以定义初始化块。
Java要求被局部内部类、匿名内部类访问的局部变量必须使用final修饰,从Java 8开始,如果局部变量被匿名内部类访问,那么该局部变量相当于自动使用了final修饰,不能再更改。这叫做“effectively final”。