静态内部类不依赖外部类实例,非静态内部类必须绑定外部类实例;前者可直接new且仅访问外部类static成员,后者需通过外部类实例创建并能访问所有成员。

核心区别就一条:静态内部类不绑外部类实例,非静态内部类必须绑。
创建方式完全不同
静态内部类像普通类一样直接 new:
-
new Outer.StaticInner()—— 不需要先创建Outer实例 - 编译后是独立的
Outer$StaticInner.class,和外部类实例毫无关系
非静态内部类必须依托外部类对象:
-
new Outer().new Inner()—— 先有外部类实例,再用它来 new 内部类 -
new Outer.Inner()会编译报错:“no enclosing instance”
能不能访问外部类成员,取决于有没有 this
静态内部类没 this,只能碰 static 成员:
- 能直接用
Outer.staticField、Outer.staticMethod() - 写
instanceField或调instanceMethod()直接编译失败 - 真要访问实例成员?得手动 new 一个外部类:
new Outer().instanceField—— 但这不是原来那个对象
非静态内部类自带隐式 this<p>非静态内部类自带隐式 <code>this$0 引用:
- 可直接读写
private int x、调void helper(),哪怕没显式写Outer.this.x - 即使代码里一句没用外部成员,
this$0依然存在——内存占着,GC 拦着
能不能定义静态成员,暴露本质差异
静态内部类本身就是“类级别”的:
- 可以声明
public static final String TAG = "xxx" - 也能写
private static int counter = 0、static void init() {}
非静态内部类生来就依附于实例:
- 除
static final编译期常量外,其他静态字段或方法一律禁止 - 因为它的存在前提就是有外部对象,和“静态”语义根本冲突
选哪个,看你要不要“看到外面的世界”
只做工具、DTO、Builder、缓存辅助?→ 优先静态内部类
要响应事件、修改外部字段、实现监听器回调?→ 必须非静态内部类
不确定?先写 static,编译报错说“无法访问非静态成员”,再改——比事后查内存泄漏省力得多
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











