java内部类有四种类型:成员内部类依附外部实例、静态内部类独立于外部实例、局部内部类限于方法内、匿名内部类无名且一次性,各自语义明确、边界清晰。

Java内部类不是语法糖,而是有明确语义和使用边界的语言特性。掌握四种类型的关键,在于理解“定义位置”和“是否依赖外部类实例”这两个维度。
成员内部类:必须依附外部类实例
定义在外部类的成员位置(和字段、方法同级),不加static修饰。它天然持有对外部类实例的引用(Outer.this),因此能直接访问外部类所有成员,包括私有字段和方法。
- 创建对象必须先有外部类实例:new Outer().new Inner()
- 不能定义普通静态成员(static字段或方法),只允许static final常量
- 可声明为private、public等任意访问修饰符,封装性极强
- 若内部类与外部类成员同名,用Outer.this.fieldName明确访问外部类变量
静态内部类:独立于外部类实例存在
同样定义在外部类的成员位置,但用static修饰。它不持有外部类实例引用,因此只能访问外部类的static成员,不能直接访问非静态字段或方法。
- 创建对象无需外部类实例:new Outer.StaticInner()
- 可以定义任意静态成员(静态字段、静态方法、静态代码块)
- 常用于工具类、Builder模式、实体类的嵌套结构(如Response.Data)
- 内存更轻量,无隐式引用导致的泄漏风险
局部内部类:限定在方法或代码块内
定义在方法、构造器或代码块内部,作用域仅限当前作用域。它既能访问外部类所有成员,也能访问所在方法的局部变量——但后者必须是effectively final(实际不可变)。
- 不能用public、private等修饰符(作用域已限定)
- 不能定义static成员(除static final常量)
- 编译后生成独立Outer$1LocalClass.class文件,命名含数字序号
- 适合封装一段临时逻辑,比如复杂计算的中间步骤或回调封装
匿名内部类:无名+一次性+接口/抽象类实现
是局部内部类的特殊形式,没有类名,定义即实例化,通常用于快速实现接口或继承抽象类。它也要求访问的局部变量为effectively final,且隐式持有外部类实例引用。
- 语法简洁:new Interface() { ... } 或 new AbstractClass() { ... }
- 不能定义构造器,不能有显式名字,无法被复用
- 是Lambda表达式的前身;当逻辑简单时,优先考虑Lambda替代
- 常见于事件监听、线程启动、集合排序器(Comparator)等场景











