局部内部类必须定义在方法、构造器或代码块内,不可修饰为public/private/static,可访问外部类所有成员及所在方法的final或effectively final变量,编译后生成outer$1.class,仅限定义方法内使用。

局部内部类必须定义在方法、构造器或代码块内部,不能出现在类的成员位置;它没有访问修饰符,也不能用 static 修饰,仅限当前作用域内使用。
定义位置和基本写法
局部内部类只能写在方法的大括号里,语法上就是一个普通类定义,只是嵌套在方法体内:
- 不能加
public、private等修饰符 - 不能用
static修饰(连static方法都不允许) - 编译后生成类似
Outer$1.class的文件,没有正式类名 - 类名合法即可,但外部代码无法通过名字引用或实例化它
能访问哪些外部元素
局部内部类可以访问:
- 外部类的所有成员(包括私有字段和方法)
- 所在方法的参数和局部变量,但这些变量必须是
final或 effectively final(Java 8 起放宽限制,语义不变)
注意:所谓“访问”不是实时读取原始变量,而是编译器把变量值复制进内部类的私有字段,并在构造时传入。
定义后如何调用
必须在同一个方法内完成定义、实例化和调用:
- 定义之后才能
new实例,不能提前使用 - 可定义多个方法、实现接口、继承父类,比匿名类更灵活
- 生命周期绑定该方法执行期,方法结束即不可再访问
- 典型写法示例:
void doWork() {
int x = 10;
class Helper {
void run() { System.out.println("x=" + x); }
}
new Helper().run(); // 必须在方法内调用
}
和匿名类、Lambda 的区别
三者都适合封装临时逻辑,但适用场景不同:
- 局部内部类:有名字、可在同方法内复用多次、支持多方法和字段,适合稍复杂行为
- 匿名内部类:无名、只能用一次、必须基于已有类型(类/接口),适合简单回调
- Lambda:仅限函数式接口、不能捕获非
final变量、不能定义状态,适合极简函数传递











