《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!

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

相关推荐
唐青枫20 小时前
Java Flyway 实战指南:用 SQL 脚本管理数据库版本
java
三品吉他手会点灯1 天前
C语言学习笔记 - 50.流程控制4 - 流程控制为什么非常非常重要
c语言·开发语言·笔记·学习
Oneslide1 天前
Ubuntu 26.04 完整安装 Fcitx5 中文拼音输入法指南(适配默认Wayland)
后端
huangdong_1 天前
电商平台图片URL原图转换技术深度解析:从缩略图到高清原图的完整方案
java·后端·spring
記億揺晃着的那天1 天前
Java 调用外部 Go 程序的实践:ProcessBuilder 在生产环境中的应用
java·golang·processbuilder
掘金码甲哥1 天前
3min手搓一个帮助文档站,很合理吧!
后端
JAVA面经实录9171 天前
Java 数据结构与算法 (终极完整学习文档)
java·数据结构·算法
JAVA面经实录9171 天前
操作系统面试题
java·服务器·数据库·计算机网络·面试
一杯奶茶¥1 天前
基于springboot的失物招领管理系统带万字文档 校园失物招领管理系统 失物认领管理系统java springboot vue
java·vue.js·spring boot·java项目
在放️1 天前
Python 爬虫 · 第三方代理接入与合规使用
开发语言·爬虫·python