《Java 100 天进阶之路》第37篇:Java内部类及其作用

第37篇:Java内部类及其作用

📌 系列导航 :《Java 100 天进阶之路》完整目录 |

⬅️ 上一篇:第36篇:选择最适合自己的NIO,一探流技术 |

➡️ 下一篇:第38篇:Java是动态语言吗?


一、核心知识点

  • 成员内部类(非静态内部类)
  • 局部内部类(方法内定义)
  • 匿名内部类(最常用)
  • 静态内部类(嵌套类)
  • 内部类的访问规则、生命周期、应用场景

二、通俗讲解(1分钟开心学)

1. 什么是内部类?

定义在另一个类内部的类。内部类可以访问外部类的所有成员(包括私有),实现更好的封装和组织。

2. 四种内部类

  • 成员内部类 :定义在外部类内部,像成员变量一样。创建时需要先有外部类实例(outer.new Inner())。
  • 静态内部类 :用 static 修饰,独立于外部类实例,不能访问外部类非静态成员。
  • 局部内部类:定义在方法内部,作用域仅限于该方法。
  • 匿名内部类:没有类名,通常用于简化代码,比如实现接口或继承类的临时实例。

3. 内部类的作用

  • 逻辑分组:把只服务于外部类的类放在内部,提高封装性。
  • 增加封装:内部类可以访问外部类私有成员。
  • 简洁代码:匿名内部类常用于事件监听、回调等。

生活类比 :

内部类就像手机里的"电池模块"。手机(外部类)的电池(内部类)可以访问手机的电量管理(私有成员)。如果电池做成静态内部类,就像可拆卸电池,不需要手机本身就能存在。

三、实操代码案例 + 场景说明

场景:设计一个迭代器(Iterator)作为外部类的内部类,用于遍历集合。

java 复制代码
import java.util.Iterator;

// 外部类:简单列表
public class MyList<T> implements Iterable<T> {
    private Object[] elements;
    private int size;
    
    public MyList(int capacity) {
        elements = new Object[capacity];
    }
    
    public void add(T item) {
        elements[size++] = item;
    }
    
    // 成员内部类:迭代器
    private class MyIterator implements Iterator<T> {
        private int cursor = 0;
        @Override
        public boolean hasNext() {
            return cursor < size;
        }
        @Override
        @SuppressWarnings("unchecked")
        public T next() {
            return (T) elements[cursor++];
        }
    }
    
    @Override
    public Iterator<T> iterator() {
        return new MyIterator();  // 创建内部类对象
    }
    
    public static void main(String[] args) {
        MyList<String> list = new MyList<>(3);
        list.add("A"); list.add("B"); list.add("C");
        for (String s : list) {
            System.out.println(s);
        }
    }
}

// === 其他内部类示例 ===
class Outer {
    private int data = 100;
    
    // 1. 成员内部类
    class Inner {
        void print() { System.out.println(data); }  // 可访问外部私有
    }
    
    // 2. 静态内部类
    static class StaticInner {
        void show() { System.out.println("静态内部类"); }
        // void printData() { System.out.println(data); } // 错误,不能访问非静态成员
    }
    
    // 3. 局部内部类(方法内)
    public void method() {
        class Local {
            void run() { System.out.println("局部内部类"); }
        }
        Local l = new Local();
        l.run();
    }
    
    // 4. 匿名内部类(常见于线程、监听器)
    public void startThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类线程");
            }
        }).start();
        
        // Java 8+ lambda 简化(当接口是函数式时)
        new Thread(() -> System.out.println("lambda")).start();
    }
}

四、避坑要点

错误/误区 后果 正确做法
成员内部类中定义静态成员 编译错误(除了静态常量) 内部类中尽量避免静态成员
匿名内部类中访问局部变量,但变量不是 final(或 effectively final) 编译错误 确保局部变量不修改
静态内部类试图访问外部类非静态成员 编译错误 只能访问外部类静态成员
内部类持有外部类引用导致内存泄漏(如 Android Handler) 外部类无法被 GC 使用静态内部类 + 弱引用

五、面试高频考点

Q1:为什么内部类可以访问外部类的私有成员?

编译器会在编译时生成一个隐式的构造方法,传入外部类的引用,并生成桥接方法访问私有成员(通过 access$0 等合成方法)。

Q2:静态内部类和非静态内部类的区别?

静态内部类不持有外部类的引用,可以独立创建;非静态内部类需要外部类实例才能创建,可以访问外部类所有成员(包括私有)。

Q3:匿名内部类如何访问外部方法的局部变量?

该局部变量必须是 final 或 effectively final(Java 8+),因为匿名内部类会复制该变量的副本,为了保持一致性要求不可变。

六、练习题

  1. 设计 :定义一个 LinkedList 类,包含内部类 Node(表示链表节点),并实现添加和遍历方法。
  2. 代码填空 :使用匿名内部类创建一个 Comparator<String>,按字符串长度降序排序。
  3. 分析:为什么在 Android 开发中,Handler 使用静态内部类 + 弱引用来避免内存泄漏?

📊 你的学习进度

  • 当前:第37篇 / 共44篇 · 第六阶段:NIO、泛型、JVM内幕、字节码(第36~44篇)
  • ✅ 已完成:第1~36篇
  • 📖 正在学:第37篇
  • ⏳ 待学习:第38~44篇

👉 📚 完整目录 & 学习指南 | 🔥 订阅本专栏,不错过每一篇

💡 本专栏每篇都包含:避坑表 + 面试高频考点 + 练习题。每天30分钟,100天拿offer!


👉 下一篇文章预告

《第38篇:Java是动态语言吗?》

内容简介:动态语言判定标准、Java静态特性、半动态特性(反射/动态代理/字节码生成)、与Python对比。

💡 学完这篇,你将理解Java的静态本质和动态能力,面试再问轻松回答。

📌 《Java 100 天进阶之路 | 从入门到上岗就业》 每天一篇,建议收藏 + 关注 ,一起100天拿offer!

👉 点击关注我,更新后第一时间收到推送!

相关推荐
此时不提桶,更待何时1 小时前
05-03-B-ClickHouse与OLAP面试与生产事故实战
clickhouse·面试·nosql
摇滚侠1 小时前
《On Java 中文版 基础卷》阅读笔记 对象无处不在 03
java·笔记·python
二十雨辰1 小时前
[学成在线]-01项目背景
java
小小小小钰儿2 小时前
1.5-Python网络编程
开发语言·网络·python·web安全·计算机·网络安全
hiahiahia1232 小时前
实现完整 Tool Dispatcher
开发语言·前端
IT_陈寒2 小时前
Java线程池这破玩意,差点让我周末加班排查到凌晨
前端·人工智能·后端
AC赳赳老秦2 小时前
公开音频转写信息提取:OpenClaw 处理发布会与听证会文本并提取核心决策信息
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
此时不提桶,更待何时2 小时前
03-04-B-连接池与DB治理面试与生产事故实战
mysql·面试
弈栈录2 小时前
Java AI 应用的异步化与高并发设计
java·后端·架构