在Java中,允许在一个类的内部定义类,这样的类称作内部类,内部类所在的类称作外部类。在实际开发中,根据内部类的位置、修饰符和定义方式的不同,内部类可分为4种,分别是成员内部类、局部内部类、静态内部类、匿名内部类。
成员内部类(Member Inner Class):
- 定义在外部类的成员位置,与外部类的实例相关联,并且没有使用 static 修饰的内部类。
- 可以直接访问外部类的所有成员,包括私有成员,并且可以通过外部类对象创建实例。
- 使用语法:外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
局部内部类(Local Inner Class):
- 定义在方法或代码块内部,作用范围仅限于所在的方法或代码块。
- 不能有访问修饰符,只能在定义它的方法或代码块中使用。
- 可以访问所在方法或代码块中的局部变量(必须是 final 或 effectively final)。
- 使用语法:class 内部类名 { ... }
静态内部类(Static Inner Class):
- 定义在外部类中,它是使用 static 修饰的内部类。
- 与外部类的实例无关,通过 外部类名.内部类名 直接访问。
- 只能直接访问外部类的静态成员并创建实例,不能访问非静态成员。
- 使用语法:外部类名.静态内部类名 变量名 = new 外部类名().静态内部类名();
匿名内部类(Anonymous Inner Class):
- 没有显式的定义,直接通过实例化接口或抽象类来创建。
- 无需命名,通常用于临时需要覆写某个方法的情况,简化代码编写。
- 可以是接口的实现类或继承自抽象类的子类。
- 使用语法:new 接口名/抽象类名() { //匿名内部类实现部分}
以下的示例,演示了不同类型的内部类的使用:
public class OuterClass {
private int outerVariable = 10;
private static int outerStaticVariable = 20;
// 成员内部类
public class MemberInnerClass {
public void display() {
System.out.println("成员内部类:" + outerVariable);
}
}
// 静态内部类
public static class StaticInnerClass {
public void display() {
System.out.println("静态内部类:" + outerStaticVariable);
}
}
// 方法示例
public void displayLocalInnerClass() {
int localVariable = 30; // 局部变量
// 局部内部类
class LocalInnerClass {
public void display() {
System.out.println("局部内部类:" + localVariable);
}
}
LocalInnerClass localInnerObj = new LocalInnerClass();
localInnerObj.display();
}
// 匿名内部类示例
public void displayAnonymousInnerClass() {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类");
}
};
Thread thread = new Thread(runnable);
thread.start();
}
public static void main(String[] args) {
OuterClass outerObj = new OuterClass();
// 使用成员内部类
OuterClass.MemberInnerClass memberInnerObj = outerObj.new MemberInnerClass();
memberInnerObj.display();//运行:成员内部类:10
// 使用静态内部类
OuterClass.StaticInnerClass staticInnerObj = new OuterClass.StaticInnerClass();
staticInnerObj.display();//静态内部类:20
// 调用局部内部类示例方法
outerObj.displayLocalInnerClass();//局部内部类:30
// 调用匿名内部类示例方法
outerObj.displayAnonymousInnerClass();//匿名内部类
}
}
这个示例中演示了四种不同类型的内部类的使用方式:
-
成员内部类(Member Inner Class):通过外部类实例创建内部类实例,能够访问外部类实例的成员变量。
-
静态内部类(Static Inner Class):直接通过外部类名访问内部类,与外部类实例无关,只能访问外部类的静态成员。
-
局部内部类(Local Inner Class):定义在方法中的内部类,仅在所在方法中可见,可以访问所在方法的局部变量,但被访问的局部变量必须是 final 或 effectively final 的。
-
匿名内部类(Anonymous Inner Class):通过实例化接口或抽象类来创建,并且没有显式的定义,常用于覆写一次性需要的方法。在示例中通过匿名内部类实现了 Runnable 接口并创建线程。