一、概念
1.定义:在一个类的内部,再定义一个完整的类,里面的类称为内部类,外面包裹它的类称为外部类。
2.核心特点
(1)内部拥有独立的类文件,编译后生成.class 文件,命名: 外部类类名$内部类类名.class
(2)内部类可以直接访问外部类所有成员(包括私有)
(3)外部类访问内部类成员,必须先创建内部类对象
(4)内部类是独立的作用域,不会和外部类成员重名冲突
3.使用场景:封装辅助逻辑、回调、简化代码(匿名内部类)
二、内部类的分类
1.成员内部类:类比于实例变量
写在外部类成员位置,不被 static 修饰。
特性
(1)以来外部类实例,必须先创建外部类对象,才能创建内部类对象
(2)不能定义静态变量、静态方法(常量 static final 除外)
(3)可直接访问外部类所有属性 / 方法,区分同名变量:外部类名.this.成员
2.静态内部类:类比于静态变量
成员位置,被 static 修饰,也叫嵌套类
特性
(1)不依赖外部类对象,可直接通过外部类类名创建
(2)只能访问外部类静态成员,不能直接访问外部实例变量
(3)可以定义静态变量、静态方法
3.局部内部类:类比于局部变量
定义在方法 / 代码块内部,作用域仅限当前方法,出方法失效
特性
(1)作用域极小,外部无法访问,仅方法内可用
(2)JDK8+ 方法中局部变量被内部类使用,自动隐式 final (不可二次修改)
(3)不能使用访问修饰符(public / private / protected)
4.匿名内部类:是一个特殊的局部内部类
没有类名的局部内部类,一次性使用,常用于接口 / 抽象类快速实现
特性
(1)没有构造方法,只有创建一次对象
(2)必须继承父类 / 实现接口
(3)本质:一次性子类实现,简化回调、线程、监听器代码
(4)匿名内部类的优缺点:
优点:减小代码量,让编程思路连贯
缺点:可读性低
三、高频面试重点
1.成员内部类为什么不能有 static 变量?
成员内部类依附外部类对象存在,静态属于类,生命周期冲突。
2.匿名内部类和 Lambda 的区别:
匿名内部类可重写多个方法;
Lambda 只能用于函数式接口(一个抽象方法)。
3.局部内部类使用局部变量为什么不能修改?
内部类对象生命周期可能长于方法局部变量,为避免数据不一致,强制隐式 final。