Java 内部类

内部类(Inner Class)是定义在另一个类内部的类。它能把"只服务于外部类"的逻辑就近封装,还能直接访问外部类的私有成员,常用于事件监听、迭代器、回调等场景。

什么是内部类

内部类天然"绑定"着外部类的一个对象,因此可以直接读写外部类的字段(包括 private),无需额外传参:

class Outer {
    private int x = 10;

    class Inner {                        // 成员内部类(非静态)
        void show() {
            System.out.println("x = " + x);   // 直接访问外部私有成员
        }
    }
}

// —— 片段需放进 main 方法中运行 ——
Outer o = new Outer();
Outer.Inner in = o.new Inner();          // 必须借助外部类对象创建
in.show();
// 输出:x = 10

静态内部类

用 static 修饰的内部类不依赖外部类对象,相当于独立类,但只能访问外部类的静态成员:

class Outer {
    static int y = 5;

    static class StaticInner {           // 静态内部类
        void show() { System.out.println("y = " + y); }
    }
}

// —— 片段需放进 main 方法中运行 ——
Outer.StaticInner si = new Outer.StaticInner();
si.show();
// 输出:y = 5

局部内部类

定义在方法内部的类叫局部内部类,作用域只限于该方法,方法结束即失效:

class Outer {
    void test() {
        class Local {                    // 局部内部类
            void hello() { System.out.println("局部内部类"); }
        }
        new Local().hello();
    }
}

// —— 片段需放进 main 方法中运行 ——
new Outer().test();
// 输出:局部内部类

匿名内部类

匿名内部类没有类名,在 new 接口或抽象类的同时直接给出实现,适合"只用一次"的逻辑:

interface Greet { void say(); }

// —— 片段需放进 main 方法中运行 ——
Greet g = new Greet() {                  // 匿名内部类:new 接口 + 实现体
    @Override public void say() {
        System.out.println("你好");
    }
};
g.say();
// 输出:你好

匿名内部类要点:语法是 new 接口/抽象类() { 实现 };只能创建一个对象;常在事件监听、线程、回调里代替写一个正式类。

lambda 简化匿名内部类

如果接口只有一个抽象方法(函数式接口),JDK8 可以用 lambda 一行替代上面的匿名内部类:

Greet g2 = () -> System.out.println("你好");   // lambda 写法
g2.say();
// 输出:你好

字节码文件名

内部类编译后会各自生成独立的 .class 文件:成员内部类叫 Outer$Inner.class,匿名内部类按出现顺序叫 Outer$1.class、Outer$2.class,局部内部类如 Outer$1Local.class。

内部类把"紧密协作的类"收拢在一起,能方便地访问外部私有成员;匿名内部类尤其擅长快速实现接口,配合 lambda 让代码更加简洁。

笔记加载中…