定义:定义在另一个类内部的类,称为内部类;外部容纳它的类叫外部类
四大分类:成员内部类、静态内部类(静态嵌套类)、局部内部类、匿名内部类
1. 成员内部类
写在外部类成员位置,没有 static 修饰
class Outer{
//成员内部类
class Inner{
}
}
- 依附外部类实例,必须先创建外部类对象,才能创建内部类对象
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
- 内部类可以直接访问外部类所有成员(包括私有)
- 内部类中不能定义静态成员(static 变量、静态方法)
- 访问外部类同名变量:
Outer.this.属性名
2. 静态内部类
使用 static 修饰,放在外部类成员位置
class Outer{
static class StaticInner{
}
}
- 不依赖外部类对象,直接通过外部类类名创建
Outer.StaticInner inner = new Outer.StaticInner();
- 只能直接访问外部类 static 静态成员,不能直接访问外部类实例成员
- 可以定义静态变量、静态方法
3. 局部内部类
定义在方法/代码块内部,作用域仅限于当前方法
class Outer{
public void test(){
//局部内部类
class LocalInner{
}
//只能在方法内创建对象
LocalInner inner = new LocalInner();
}
}
- 作用域很小,方法外面无法使用
- JDK8+ 访问方法局部变量,变量必须是 final / 有效final
- 不能使用访问修饰符(public/private/protected)
4. 匿名内部类
没有类名的局部内部类,一次性使用,配合接口/抽象类使用
interface Animal{
void shout();
}
public class Test{
public static void main(String[] args) {
//匿名内部类
Animal a = new Animal() {
@Override
public void shout() {
System.out.println("叫一声");
}
};
a.shout();
}
}
- 没有类名,只能创建唯一一个实例
- 只能实现一个接口 / 继承一个父类
- 不能定义静态成员、不能有构造方法
- Lambda 可以简化只有一个抽象方法的匿名内部类
| 类型 | static修饰 | 创建对象是否需要外部类实例 | 能否直接访问外部类实例成员 |
|---|---|---|---|
| 成员内部类 | ❌ | ✅ 需要 | ✅ 可以直接访问 |
| 静态内部类 | ✅ | ❌ 不需要 | ❌ 只能访问静态成员 |
| 局部内部类 | 不允许static | 方法内创建 | 有效final局部变量+外部成员 |
| 匿名内部类 | 不允许static | 定义时直接new | 有效final局部变量+外部成员 |
- 静态内部类官方标准名称:静态嵌套类,很多教材俗称静态内部类;
- 成员内部类不能拥有静态方法;静态内部类无此限制;
- 匿名内部类 ≠ Lambda,Lambda 只是简化【函数式接口】的匿名内部类;
- 内部类会生成独立class文件:
Outer$Inner.class