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

核心就一条:静态内部类不绑外部类实例,非静态内部类必须绑。
创建方式完全不同
静态内部类像普通类一样直接 new:
new Outer.StaticInner() —— 不需要先创建 Outer 实例
编译后是独立的 Outer$StaticInner.class,和外部类对象完全无关。
非静态内部类必须依托外部类对象:
new Outer().new Inner() —— 先得有 Outer 实例,再用它 new 内部类
new Outer.Inner() 会编译报错:“no enclosing instance”
能不能访问外部类成员,取决于有没有 this
静态内部类没 this,只能碰 static 成员:
• 能直接用 Outer.staticField、Outer.staticMethod()
• 写 instanceField 或调 instanceMethod() 直接编译失败
• 真要访问实例成员?得手动 new 一个外部类:new Outer().instanceField —— 但这不是原来那个对象
非静态内部类自带隐式 this$0 引用:
• 能直接读写外部类所有成员(包括 private 字段和方法)
• 即使代码里一句没用到外部类成员,this$0 依然存在,内存和 GC 都受影响
内存与生命周期差异明显
静态内部类不持外部类引用:
• 创建更快、更轻量,省下 4–8 字节引用空间
• GC 更友好:外部类对象即使不可达,静态内部类实例仍可安全存活
非静态内部类强绑定外部实例:
• 每个实例都悄悄绑着一个 this$0,躲不掉
• 无法单独序列化(会抛 NotSerializableException)
• 不能在 static 方法或静态代码块中直接 new
• 若外部类持有大对象(如缓存 Map),内部类会间接阻止其回收
能不能定义静态成员,也由此决定
静态内部类自身就是“类级别”的:
• 可以定义静态字段、静态方法、静态代码块
• 完全符合 static 的语义
非静态内部类存在前提就是有外部实例:
• 不能定义静态成员(除 static final 基本类型或 String 常量)
• 否则语义冲突:一个依附于对象的东西,怎么又属于类本身?
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











