内部类(Inner Class),是
Java 中对类的一种定义方式,是
嵌套类的一个分类,即非
静态嵌套类(Non-Static Nested Class)。内部类(非静态嵌套类)分为
成员内部类、局部内部类和匿名内部类三种。
定义
以下内容来自
Java 官方教程中的《嵌套类》章节。
Java 编程语言允许一个类被定义在另一个类中,这样的类就称为嵌套类。嵌套类分为两种:静态的和非静态的。没有用 static 关键字来声明的嵌套类,就称为非
静态嵌套类。非静态嵌套类,又称为内部类。内部类还有两个特殊的类型:
局部类(Local Class)和
匿名类(Anonymous Class)。
包含嵌套类的类,可称为外围类(Enclosing Class)或外部类(Outer Class)。非静态嵌套类(内部类)可访问其外围类的其他成员,即使这些成员被声明为私有的。若内部类作为其外部类的成员,则它可声明为 private、public、protected 或包私有的。
内容简介
作为其外部类成员的内部类,称为
成员内部类。除另有说明外,“内部类”通常是指成员内部类。
与实例的方法和变量一样,内部类与其外围类的实例相关联,并可
直接访问该外围类对象的方法和字段。此外,由于内部类与实例相关联,因此不能在内部类中定义任何
静态成员。
在上述示例中,InnerClass 类的实例只能存在于 OuterClass 类的实例中,并且可以直接访问 OuterClass 类的实例的方法和字段。
要实例化内部类,就必须首先实例化外部类。然后,使用以下语法在外部对象中创建内部对象:
可以用内部类来实现助手类(Helper Class)。如要处理
用户界面的事件,就必须知道如何使用内部类,因为内部类广泛地使用在
事件处理机制上。
遮蔽 - 重名问题
在上述示例中,外部类的
字符串成员变量、内部类的字符串成员变量和内部类方法的字符串
局部变量发生重名,则内部类方法的字符串局部变量的声明,遮蔽了外部类和内部类中的同名成员变量的
作用域(如同将二者隐藏起来),使二者不能仅以名称来引用。
同样的,外部类的
整型成员变量、内部类的整型成员变量和内部类方法的整型参数发生重名,则内部类方法的整型参数的声明,遮蔽了外部类和内部类中的同名成员变量的作用域(如同将二者隐藏起来),使二者不能仅以名称来访问使用。
如需在内部类方法中访问内部类的重名成员变量,请使用 this 关键字,如下:
如需在内部类方法中访问外部类的重名成员变量,请使用外部类名加 this 关键字,如下:
禁止序列化 - 兼容性问题
Java 语言强烈建议禁止对内部类(包括局部类和匿名类)进行序列化。
当 Java
编译器编译某些
构造方法(如内部类)时,它会创建合成结构。与合成结构相关的类及其构造方法、字段和方法,在
源代码中是没有的。合成结构能使 Java 编译器实现新的 Java 语言特性,而无需对
JVM 进行更改。
然而,不同的 Java 编译器可能会创建不同的合成结构,这意味着 .class 文件在不同的实现中也会有所不同。因此,如果将内部类序列化,然后用不同的
JRE 将其反序列化,则可能会出现
兼容性问题。
局部类和匿名类
局部类和匿名类是内部类的两个特殊的类型。
在方法体中声明的内部类,称为局部内部类,亦称局部类。局部类是有类名的。
在方法体中声明的无需命名的内部类,称为匿名内部类,亦称匿名类。匿名类是没有类名的。