Java 内部类指南

📌 内部类是什么?

定义在另一个类内部的类,可以更好地封装和代码组织。

🎯 四种内部类(一句话概括)

类型 关键字 一句话说明
成员内部类 无特殊 像普通成员一样,依赖外部实例
静态内部类 static 不依赖外部实例,常用工具类
局部内部类 定义在方法内 方法内部使用,不能有访问修饰符
匿名内部类 无类名 一次性使用,直接new接口/类

💡 1. 成员内部类(最常用)

java 复制代码
// 外部类
class Outer {
    private String outerField = "外部数据";
    
    // 成员内部类
    class Inner {
        public void show() {
            System.out.println("访问外部数据: " + outerField);
        }
    }
}

// 使用
public class Demo {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();  // 先有外部,再有内部
        inner.show();
    }
}

💡 2. 静态内部类(推荐)

java 复制代码
class Outer {
    // 静态内部类
    static class StaticInner {
        public void show() {
            System.out.println("我是静态内部类");
        }
    }
}

// 使用(不需要外部实例)
public class Demo {
    public static void main(String[] args) {
        Outer.StaticInner inner = new Outer.StaticInner();
        inner.show();
    }
}

💡 3. 局部内部类(方法内定义)

java 复制代码
class Outer {
    public void method() {
        // 局部内部类(只能在方法内使用)
        class LocalInner {
            public void show() {
                System.out.println("我是局部内部类");
            }
        }
        
        LocalInner inner = new LocalInner();
        inner.show();
    }
}

💡 4. 匿名内部类(快速实现接口)

java 复制代码
// 接口
interface Animal {
    void makeSound();
}

public class Demo {
    public static void main(String[] args) {
        // 匿名内部类:直接new接口
        Animal dog = new Animal() {
            @Override
            public void makeSound() {
                System.out.println("汪汪");
            }
        };
        
        dog.makeSound();
        
        // Java 8+ 更简单的写法(Lambda)
        Animal cat = () -> System.out.println("喵喵");
        cat.makeSound();
    }
}

🔑 关键区别速查

特性 成员内部类 静态内部类 局部内部类 匿名内部类
需要外部实例 ✅ 必须 ❌ 不需要 ✅ 需要 ✅ 需要
访问外部字段 ✅ 可以 ❌ 不能* ✅ 可以 ✅ 可以
定义位置 类中 类中 方法中 直接new
访问修饰符 可以有 可以有 不能有 不能有
使用频率 经常 经常 较少 经常

*静态内部类可以通过创建外部实例来访问

🚀 快速选择指南

markdown 复制代码
问:用哪种内部类?

1. 需要多次使用,且和外部类相关?
   - 是 → 用成员内部类
   - 否 → 继续

2. 只是工具类,不依赖外部实例?
   - 是 → 用静态内部类 ✅(推荐)
   - 否 → 继续

3. 只在某个方法里用?
   - 是 → 用局部内部类
   - 否 → 继续

4. 一次性使用,实现接口?
   - 是 → 用匿名内部类

💎 实际应用场景

场景1:迭代器(成员内部类)

java 复制代码
class MyList {
    private String[] data = {"A", "B", "C"};
    
    // 内部类实现迭代器
    class MyIterator {
        private int index = 0;
        boolean hasNext() { return index < data.length; }
        String next() { return data[index++]; }
    }
    
    MyIterator iterator() {
        return new MyIterator();
    }
}

场景2:建造者模式(静态内部类)

java 复制代码
class Person {
    private Person(Builder builder) { /* ... */ }
    
    // 静态内部类作为建造者
    static class Builder {
        private String name;
        
        Builder name(String name) {
            this.name = name;
            return this;
        }
        
        Person build() {
            return new Person(this);
        }
    }
}

// 使用
Person p = new Person.Builder().name("张三").build();

场景3:事件监听(匿名内部类)

java 复制代码
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick() {
        System.out.println("按钮被点击");
    }
});

⚠️ 注意事项

  1. 成员内部类持有外部类引用,注意内存泄漏
  2. 匿名内部类只能访问final局部变量
  3. 静态内部类不能直接访问外部实例成员
  4. 内部类编译后生成:Outer$Inner.class

📝 一句话总结

成员内部类 像成员,静态内部类 像工具,局部内部类 在方法里,匿名内部类 一次用。大部分情况用静态内部类最安全!

相关推荐
程序员西西1 小时前
作为开发,你真的懂 OOM 吗?实测 3 种场景,搞懂 JVM 崩溃真相
java·后端
开心就好20251 小时前
Fiddler抓包与接口调试实战,HTTPHTTPS配置、代理设置与移动端抓包详解
后端
u***28471 小时前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
古城小栈1 小时前
SpringBoot项目集成第三方CAS-client jar包
spring boot·后端·jar
期待のcode1 小时前
Springboot数据层开发
java·spring boot·后端
未来coding1 小时前
Spring AI ChatModel API 详解【基于官方文档】
java·后端·spring
无限进步_1 小时前
C语言双向循环链表实现详解:哨兵位与循环结构
c语言·开发语言·数据结构·c++·后端·算法·链表
bcbnb1 小时前
Charles抓包怎么用 Charles抓包工具详细教程、网络调试方法、HTTPS配置与手机抓包实战
后端
傲文博一2 小时前
为什么我的产品尽量不用「外置」动态链接库
前端·后端