Java 内部类

定义:定义在另一个类内部的类,称为内部类;外部容纳它的类叫外部类

四大分类:成员内部类、静态内部类(静态嵌套类)、局部内部类、匿名内部类

1. 成员内部类

写在外部类成员位置,没有 static 修饰

class Outer{
    //成员内部类
    class Inner{

    }
}
  1. 依附外部类实例,必须先创建外部类对象,才能创建内部类对象
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
  1. 内部类可以直接访问外部类所有成员(包括私有)
  2. 内部类中不能定义静态成员(static 变量、静态方法)
  3. 访问外部类同名变量:Outer.this.属性名

2. 静态内部类

使用 static 修饰,放在外部类成员位置

class Outer{
    static class StaticInner{

    }
}
  1. 不依赖外部类对象,直接通过外部类类名创建
Outer.StaticInner inner = new Outer.StaticInner();
  1. 只能直接访问外部类 static 静态成员,不能直接访问外部类实例成员
  2. 可以定义静态变量、静态方法

3. 局部内部类

定义在方法/代码块内部,作用域仅限于当前方法

class Outer{
    public void test(){
        //局部内部类
        class LocalInner{

        }
        //只能在方法内创建对象
        LocalInner inner = new LocalInner();
    }
}
  1. 作用域很小,方法外面无法使用
  2. JDK8+ 访问方法局部变量,变量必须是 final / 有效final
  3. 不能使用访问修饰符(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();
    }
}
  1. 没有类名,只能创建唯一一个实例
  2. 只能实现一个接口 / 继承一个父类
  3. 不能定义静态成员、不能有构造方法
  4. Lambda 可以简化只有一个抽象方法的匿名内部类

类型 static修饰 创建对象是否需要外部类实例 能否直接访问外部类实例成员
成员内部类 ✅ 需要 ✅ 可以直接访问
静态内部类 ❌ 不需要 ❌ 只能访问静态成员
局部内部类 不允许static 方法内创建 有效final局部变量+外部成员
匿名内部类 不允许static 定义时直接new 有效final局部变量+外部成员
  1. 静态内部类官方标准名称:静态嵌套类,很多教材俗称静态内部类;
  2. 成员内部类不能拥有静态方法;静态内部类无此限制;
  3. 匿名内部类 ≠ Lambda,Lambda 只是简化【函数式接口】的匿名内部类;
  4. 内部类会生成独立class文件:Outer$Inner.class
上一篇
下一篇