内部类
静态内部类(静态变量)
静态内部类是一种定义在类内部并且用 static 修饰的类
java
public class OuterClass {
private static String staticOuterField = "静态外部字段";
private String instanceOuterField = "实例外部字段";
// 静态内部类
public static class StaticInnerClass {
private String innerField = "内部字段";
public void print() {
// 可以访问外部类的静态成员
System.out.println("访问外部静态字段: " + staticOuterField);
// 不能直接访问外部类的实例字段
// System.out.println(instanceOuterField); // 编译错误
}
}
}- 使用静态内部类就需要创建静态内部类的实例
静态内部类不依赖外部类的实例,可以直接通过外部类名访问并创建实例。
java
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();
inner.print();- 静态内部类可以直接访问外部类的
static成员(字段或方法),但不能直接访问外部类的实例成员。
java
public class Outer {
// 外部类的静态成员
private static String staticField = "外部静态字段";
private static void staticMethod() {
System.out.println("调用外部静态方法");
}
// 外部类的实例成员
private String instanceField = "外部实例字段";
private void instanceMethod() {
System.out.println("调用外部实例方法");
}
// 静态内部类
public static class StaticInner {
public void testAccess() {
// ✅ 可以访问外部类的静态字段和静态方法
System.out.println("静态字段: " + staticField);
staticMethod();
// ❌ 不能直接访问外部类的实例字段和实例方法
// System.out.println(instanceField); // 编译错误
// instanceMethod(); // 编译错误
}
}
public static void main(String[] args) {
Outer.StaticInner inner = new Outer.StaticInner();
inner.testAccess();
}
}- 普通内部类不允许有静态成员,而静态内部类允许。
java
public static class StaticInnerClass {
public static final String CONST = "常量";
}实例内部类(实例变量)
实例内部类(Inner Class / 非静态内部类) 是 定义在类内部,并且没有使用 static 修饰的类。它依赖于外部类对象存在,因此 必须先创建外部类对象,才能创建实例内部类对象。
java
class Outer {
private String name = "Outer";
// 实例内部类
class Inner {
public void show() {
System.out.println("外部类属性:" + name);
}
}
}- 实例化
java
public class Test {
public static void main(String[] args) {
Outer outer = new Outer(); // 创建外部类对象
Outer.Inner inner = outer.new Inner(); // 创建内部类对象
inner.show();
}
}- 可以访问外部类的所有成员
java
class Outer {
private int age = 18;
class Inner {
public void print() {
System.out.println(age); // 可以访问private
}
}
}- 实例内部类不能定义
static成员
实例内部类依赖外部类对象存在,而 static 成员属于类级别,不依赖对象。
局部内部类(局部变量)
局部内部类 是 定义在方法、代码块或构造器内部的类。它的作用范围 只在所在的方法或代码块内部,离开这个作用域就无法访问。
java
class Outer {
public void show() {
// 局部内部类
class Inner {
public void print() {
System.out.println("局部内部类");
}
}
Inner inner = new Inner();
inner.print();
}
}局部内部类 可以访问方法中的局部变量,但必须是 final
java
class Outer {
public Runnable getRunnable() {
int num = 10;
class Inner implements Runnable {
public void run() {
System.out.println(num);
}
}
return new Inner();
}
}java
Outer outer = new Outer();
Runnable r = outer.getRunnable();
r.run();调用 getRunnable()
↓
创建 Inner 对象(在堆中)
↓
方法结束
↓
栈变量 num 消失
↓
Inner 对象仍然存在Inner 对象仍然存在,虽然仍然能够访问num,但是访问的是num的副本,因此num只有是final的才能保证程序是正确的
实际上局部内部类使用的局部变量,就算你没有加final,也会被编译器加上final
匿名内部类
匿名内部类 是 没有类名的内部类,通常用于 只需要创建一次对象的场景。它本质上是 局部内部类的简化写法。
java
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
computer.useUSB(new USB() {
@Override
public void open() {
System.out.println("U盘连接");
}
@Override
public void close() {
System.out.println("U盘拔出");
}
});
}
}java
class Computer {
public void useUSB(USB usb) {
usb.open();
System.out.println("设备正在使用...");
usb.close();
}
}new 接口 {}表示去实现一个接口,创建的对象直接传入形参,没有名字。匿名内部类支持创建接口和父类的子类实例
这个实现类只在此使用一次,因此无需创建一个单独的文件。
