当前位置: 首页 > ai >正文

Java内部类详细教程

文章目录

    • 1. 内部类基础概念
      • 1.1 什么是内部类
      • 1.2 为什么需要内部类
      • 1.3 内部类的分类
    • 2. 成员内部类
      • 2.1 成员内部类的定义和特点
      • 2.2 成员内部类的创建和使用
      • 2.3 成员内部类的访问权限
      • 2.4 成员内部类与外部类的this引用
    • 3. 静态内部类
      • 3.1 静态内部类的定义和特点
      • 3.2 静态内部类的使用
      • 3.3 静态内部类的实际应用 - 建造者模式
    • 4. 局部内部类
      • 4.1 局部内部类的定义和特点
      • 4.2 局部内部类的实际应用
      • 4.3 局部内部类与变量捕获
    • 5. 匿名内部类
      • 5.1 匿名内部类的定义和特点
      • 5.2 匿名内部类的常见应用
    • 6. 内部类的访问规则
      • 6.1 内部类访问外部类
      • 6.2 外部类访问内部类
      • 6.3 内部类的继承
    • 7. 内部类的应用场景
      • 7.1 迭代器模式
      • 7.2 观察者模式
      • 7.3 工厂模式与内部类
    • 8. 最佳实践
      • 8.1 内部类使用准则
      • 8.2 性能考虑
      • 8.3 线程安全考虑
      • 8.4 代码组织和设计原则
    • 9. 常见问题和解决方案
      • 9.1 编译错误问题
      • 9.2 内存泄漏问题
      • 9.3 序列化问题
    • 10. Lambda表达式与内部类对比
      • 10.1 从匿名内部类到Lambda表达式
      • 10.2 性能对比
    • 11. 高级主题
      • 11.1 内部类的反射操作
      • 11.2 内部类的字节码分析
      • 11.3 内部类与设计模式的深度结合
    • 12. 总结
      • 12.1 内部类知识点总结
      • 12.2 最佳实践建议
      • 12.3 学习建议

1. 内部类基础概念

1.1 什么是内部类

内部类(Inner Class)是定义在另一个类内部的类。在Java中,内部类是一个强大的特性,它允许你将逻辑相关的类组织在一起,提供更好的封装性和代码组织结构。

内部类的基本语法:

public class OuterClass {// 外部类的成员private int outerField = 10;// 内部类class InnerClass {private int innerField = 20;public void display() {System.out.println("外部类字段: " + outerField);System.out.println("内部类字段: " + innerField);}}
}

1.2 为什么需要内部类

  1. 逻辑分组: 当一个类只对另一个类有用时,将其作为内部类是合理的
  2. 增强封装: 内部类可以访问外部类的私有成员
  3. 提高可读性和可维护性: 将小的类放在使用它们的地方附近
  4. 实现多重继承: Java通过内部类可以间接实现多重继承

1.3 内部类的分类

Java中有四种类型的内部类:

  1. 成员内部类(Member Inner Class): 定义在外部类中的普通内部类
  2. 静态内部类(Static Inner Class): 使用static修饰的内部类
  3. 局部内部类(Local Inner Class): 定义在方法内部的类
  4. 匿名内部类(Anonymous Inner Class): 没有名字的内部类

2. 成员内部类

2.1 成员内部类的定义和特点

成员内部类是最常见的内部类类型,它作为外部类的一个成员存在。

基本特点:

  • 可以访问外部类的所有成员(包括私有成员)
  • 不能定义静态成员(除了静态常量)
  • 外部类可以访问内部类的私有成员
  • 内部类对象必须依赖于外部类对象
public class Computer {private String brand;private double price;public Computer(String brand, double price) {this.brand = brand;this.price = price;}// 成员内部类public class CPU {private String model;private double frequency;public CPU(String model, double frequency) {this.model = model;this.frequency = frequency;}public void displayInfo() {// 可以直接访问外部类的私有成员System.out.println("电脑品牌: " + brand);System.out.println("电脑价格: " + price);System.out.println("CPU型号: " + model);System.out.println("CPU频率: " + frequency + "GHz");}public void upgradeComputer() {// 内部类可以修改外部类的成员price += 500; // 升级CPU,电脑价格增加System.out.println("升级后价格: " + price);}}// 外部类方法可以访问内部类的私有成员public void createCPU() {CPU cpu = new CPU("Intel i7", 3.2);System.out.println("创建了CPU: " + cpu.model); // 访问内部类私有成员}
}

2.2 成员内部类的创建和使用

public class InnerClassDemo {public static void main(String[] args) {// 方式1: 先创建外部类对象,再创建内部类对象Computer computer = new Computer("联想", 5000);Computer.CPU cpu = computer.new CPU("Intel i5", 2.8);cpu.displayInfo();System.out.println("---");// 方式2: 链式创建Computer.CPU cpu2 = new Computer("华硕", 6000).new CPU("AMD Ryzen", 3.0);cpu2.displayInfo();cpu2.upgradeComputer();}
}

2.3 成员内部类的访问权限

成员内部类可以使用任何访问修饰符:

public class AccessModifierDemo {private int privateField = 1;protected int protectedField = 2;public int publicField = 3;int defaultField = 4;// public内部类public class PublicInner {public void display() {System.out.println("可以访问外部类所有成员:");System.out.println("private: " + privateField);System.out.println("protected: " + protectedField);System.out.println("public: " + publicField);System.out.println("default: " + defaultField);}}// private内部类private class PrivateInner {public void secretOperation() {System.out.println("这是私有内部类,只能在外部类内部使用");privateField = 100; // 可以修改外部类私有成员}}// protected内部类protected class ProtectedInner {public void protectedMethod() {System.out.println("受保护的内部类");}}// 外部类方法使用私有内部类public void usePrivateInner() {PrivateInner inner = new PrivateInner();inner.secretOperation();System.out.println("私有字段被修改为: " + privateField);}
}

2.4 成员内部类与外部类的this引用

public class ThisReferenceDemo {private String name = "外部类";public class Inner {private String name = "内部类";public void showNames() {String name = "局部变量";System.out.println("局部变量 name: " + name);System.out.println("内部类成员 name: " + this.name);System.out.println("外部类成员 name: " + ThisReferenceDemo.this.name);}public void callOuterMethod() {ThisReferenceDemo.this.outerMethod(); // 调用外部类方法}}public void outerMethod() {System.out.println("这是外部类的方法");}public static void main(String[] args) {ThisReferenceDemo outer = new ThisReferenceDemo();ThisReferenceDemo.Inner inner = outer.new Inner();inner.showNames();inner.callOuterMethod();}
}

3. 静态内部类

3.1 静态内部类的定义和特点

静态内部类(也称为嵌套类)使用static关键字修饰,它不需要外部类的实例就可以创建。

基本特点:

  • 不能访问外部类的非静态成员
  • 可以访问外部类的静态成员(包括私有静态成员)
  • 可以定义静态成员和非静态成员
  • 创建时不需要外部类实例
public class MathUtils {private static String version = "1.0";private String instanceField = "实例字段";// 静态内部类public static class Calculator {private double result;public Calculator() {System.out.println("创建计算器,版本: " + version); // 可以访问外部类静态成员// System.out.println(instanceField); // 编译错误!不能访问外部类非静态成员}public double add(double a, double b) {result = a + b;return result;}public double subtract(double a, double b) {result = a - b;return result;}public double getResult() {return result;}// 静态内部类可以有静态方法public static void printVersion() {System.out.println("计算器版本: " + version);}}// 外部类的静态方法public static void printInfo() {System.out.println("MathUtils 版本: " + version);}
}

3.2 静态内部类的使用

public class StaticInnerClassDemo {public static void main(String[] args) {// 直接通过外部类名创建静态内部类对象MathUtils.Calculator calc = new MathUtils.Calculator();// 使用计算器double sum = calc.add(10, 5);System.out.println("10 + 5 = " + sum);double diff = calc.subtract(10, 5);System.out.println("10 - 5 = " + diff);System.out.println("当前结果: " + calc.getResult());// 调用静态方法MathUtils.Calculator.printVersion();}
}

3.3 静态内部类的实际应用 - 建造者模式

public class Person {private final String name;private final int age;private final String email;private final String phone;private final String address;// 私有构造函数private Person(Builder builder) {this.name = builder.name;this.age = builder.age;this.email = builder.email;this.phone = builder.phone;this.address = builder.address;}// 静态内部类 - 建造者public static class Builder {// 必需参数private final String name;private final int age;// 可选参数private String email = "";private String phone = "";private String address = "";public Builder(String name, int age) {this.name = name;this.age = age;}public Builder email(String email) {this.email = email;return this;}public Builder phone(String phone) {this.phone = phone;return this;}public Builder address(String address) {this.address = address;return this;}public Person build() {return new Person(this);}}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", email='" + email + '\'' +", phone='" + phone + '\'' +", address='" + address + '\'' +'}';}
}// 使用建造者模式
class BuilderPatternDemo {public static void main(String[] args) {// 创建Person对象Person person1 = new Person.Builder("张三", 25).email("zhangsan@example.com").phone("13888888888").address("北京市朝阳区").build();System.out.println(person1);// 只设置必需参数Person person2 = new Person.Builder("李四", 30).build();System.out.println(person2);}
}

4. 局部内部类

4.1 局部内部类的定义和特点

局部内部类是定义在方法、构造函数或代码块内部的类。

基本特点:

  • 只能在定义它的方法内部使用
  • 可以访问外部类的所有成员
  • 可以访问方法的final参数和局部变量(Java 8后可以是effectively final)
  • 不能使用访问修饰符
  • 不能定义静态成员
public class LocalInnerClassDemo {private String outerField = "外部类字段";public void method1() {final String finalLocalVar = "final局部变量";String effectivelyFinalVar = "effectively final变量";// effectivelyFinalVar = "修改"; // 如果修改了,就不是effectively final了// 局部内部类class LocalInner {private String innerField = "局部内部类字段";public void display() {System.out.println("外部类字段: " + outerField);System.out.println("final局部变量: " + finalLocalVar);System.out.println("effectively final变量: " + effectivelyFinalVar);System.out.println("内部类字段: " + innerField);}public void modifyOuter() {outerField = "被局部内部类修改";}}// 在方法内使用局部内部类LocalInner inner = new LocalInner();inner.display();inner.modifyOuter();System.out.println("修改后的外部类字段: " + outerField);}public void method2() {// 局部内部类只在定义它的方法内可见// LocalInner inner = new LocalInner(); // 编译错误!}
}

4.2 局部内部类的实际应用

public interface EventListener {void onEvent(String event);
}public class EventManager {private String managerName;public EventManager(String name) {this.managerName = name;}public EventListener createListener(String listenerType) {final String type = listenerType; // effectively final// 局部内部类实现接口class ConcreteEventListener implements EventListener {private int eventCount = 0;@Overridepublic void onEvent(String event) {eventCount++;System.out.println(managerName + " 的 " + type + " 监听器");System.out.println("处理事件: " + event);System.out.println("已处理事件数: " + eventCount);System.out.println("---");}public int getEventCount() {return eventCount;}}return new ConcreteEventListener();}public static void main(String[] args) {EventManager manager = new EventManager("主事件管理器");EventListener listener1 = manager.createListener("点击");EventListener listener2 = manager.createListener("键盘");listener1.onEvent("鼠标左键点击");listener1.onEvent("鼠标右键点击");listener2.onEvent("按下Enter键");listener2.onEvent("按下Esc键");}
}

4.3 局部内部类与变量捕获

public class VariableCaptureDemo {public Runnable createRunnable(String prefix) {int count = 0; // 局部变量class LocalRunnable implements Runnable {@Overridepublic void run() {// 可以访问effectively final的局部变量System.out.println(prefix + ": 执行任务");// count++; // 编译错误!不能修改捕获的局部变量}}return new LocalRunnable();}public Runnable createRunnableWithCounter() {// 使用数组或对象来实现可变的计数器final int[] counter = {0};class CounterRunnable implements Runnable {@Overridepublic void run() {counter[0]++; // 可以修改数组内容System.out.println("执行次数: " + counter[0]);}}return new CounterRunnable();}public static void main(String[] args) {VariableCaptureDemo demo = new VariableCaptureDemo();Runnable task1 = demo.createRunnable("任务1");task1.run();Runnable task2 = demo.createRunnableWithCounter();task2.run();task2.run();task2.run();}
}

5. 匿名内部类

5.1 匿名内部类的定义和特点

匿名内部类是没有类名的内部类,通常用于创建只使用一次的类实例。

基本特点:

  • 没有类名
  • 没有构造函数(但可以有初始化块)
  • 通常用于实现接口或继承类
  • 可以访问外部类的所有成员
  • 可以访问final或effectively final的局部变量
// 定义接口
interface Greeting {void sayHello(String name);
}// 定义抽象类
abstract class Animal {protected String name;public Animal(String name) {this.name = name;}public abstract void makeSound();public void eat() {System.out.println(name + " 正在吃东西");}
}public class AnonymousClassDemo {private String ownerName = "主人";public void demonstrateAnonymousClass() {// 1. 实现接口的匿名内部类Greeting greeting = new Greeting() {@Overridepublic void sayHello(String name) {System.out.println(ownerName + " 对 " + name + " 说:你好!");}};greeting.sayHello("张三");// 2. 继承抽象类的匿名内部类Animal dog = new Animal("小狗") {// 初始化块(相当于构造函数){System.out.println("创建了一只" + name);}@Overridepublic void makeSound() {System.out.println(name + " 汪汪叫");}// 可以添加新方法public void wagTail() {System.out.println(name + " 摇尾巴");}};dog.makeSound();dog.eat();// dog.wagTail(); // 编译错误!引用类型是Animal,看不到新方法// 3. 继承具体类的匿名内部类Thread thread = new Thread() {@Overridepublic void run() {System.out.println("匿名线程正在运行: " + Thread.currentThread().getName());}};thread.start();}public static void main(String[] args) {AnonymousClassDemo demo = new AnonymousClassDemo();demo.demonstrateAnonymousClass();}
}

5.2 匿名内部类的常见应用

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.concurrent.Callable;public class AnonymousClassApplications {// 1. 事件处理(GUI编程)public void guiEventHandling() {// 模拟按钮点击事件处理ActionListener listener = new ActionListener() {private int clickCount = 0;@Overridepublic void actionPerformed(ActionEvent e) {clickCount++;System.out.println("按钮被点击了 " + clickCount + " 次");}};// 模拟点击事件listener.actionPerformed(null);listener.actionPerformed(null);}// 2. 集合排序public void collectionSorting() {List<String> names = new ArrayList<>(Arrays.asList("张三", "李四", "王五", "赵六"));// 使用匿名内部类实现ComparatorCollections.sort(names, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {// 按字符串长度排序return Integer.compare(s1.length(), s2.length());}});System.out.println("按长度排序: " + names);// 按字典序倒序排序Collections.sort(names, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s2.compareTo(s1);}});System.out.println("字典序倒序: " + names);}// 3. 线程创建public void threadCreation() {// 方式1: 继承Thread类Thread thread1 = new Thread() {@Overridepublic void run() {for (int i = 1; i <= 3; i++) {System.out.println("Thread1 - " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}};// 方式2: 实现Runnable接口Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {for (int i = 1; i <= 3; i++) {System.out.println("Thread2 - " + i);try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}}}});thread1.start();thread2.start();}// 4. 回调函数public interface Callback {void onSuccess(String result);void onError(String error);}public void processData(String data, Callback callback) {new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000); // 模拟处理时间if (data != null && !data.isEmpty()) {callback.onSuccess("处理成功: " + data.toUpperCase());} else {callback.onError("数据为空");}} catch (InterruptedException e) {callback.onError("处理被中断");}}}).start();}public void callbackExample() {processData("hello world", new Callback() {@Overridepublic void onSuccess(String result) {System.out.println("成功: " + result);}@Overridepublic void onError(String error) {System.out.println("错误: " + error);}});}public static void main(String[] args) throws InterruptedException {AnonymousClassApplications demo = new AnonymousClassApplications();System.out.println("1. GUI事件处理:");demo.guiEventHandling();System.out.println("\n2. 集合排序:");demo.collectionSorting();System.out.println("\n3. 线程创建:");demo.threadCreation();System.out.println("\n4. 回调函数:");demo.callbackExample();// 等待线程执行完成Thread.sleep(5000);}
} 

6. 内部类的访问规则

6.1 内部类访问外部类

public class AccessRulesDemo {private String privateField = "私有字段";protected String protectedField = "受保护字段";public String publicField = "公有字段";String defaultField = "默认字段";private static String staticPrivateField = "私有静态字段";public static String staticPublicField = "公有静态字段";private void privateMethod() {System.out.println("私有方法被调用");}public void publicMethod() {System.out.println("公有方法被调用");}private static void staticPrivateMethod() {System.out.println("私有静态方法被调用");}// 成员内部类public class MemberInner {public void accessOuter() {// 可以访问外部类的所有成员(包括私有)System.out.println("访问外部类私有字段: " + privateField);System.out.println("访问外部类受保护字段: " + protectedField);System.out.println("访问外部类公有字段: " + publicField);System.out.println("访问外部类默认字段: " + defaultField);// 可以访问外部类的静态成员System.out.println("访问外部类私有静态字段: " + staticPrivateField);System.out.println("访问外部类公有静态字段: " + staticPublicField);// 可以调用外部类的所有方法privateMethod();publicMethod();staticPrivateMethod();}}// 静态内部类public static class StaticInner {public void accessOuter() {// 只能访问外部类的静态成员System.out.println("访问外部类私有静态字段: " + staticPrivateField);System.out.println("访问外部类公有静态字段: " + staticPublicField);// 可以调用外部类的静态方法staticPrivateMethod();// 不能访问外部类的非静态成员// System.out.println(privateField); // 编译错误!// publicMethod(); // 编译错误!}}public void localInnerExample() {final String localVar = "局部变量";// 局部内部类class LocalInner {public void accessVariables() {// 可以访问外部类的所有成员System.out.println("访问外部类私有字段: " + privateField);// 可以访问final或effectively final的局部变量System.out.println("访问局部变量: " + localVar);// 可以调用外部类方法privateMethod();}}LocalInner inner = new LocalInner();inner.accessVariables();}
}

6.2 外部类访问内部类

public class OuterAccessInnerDemo {// 成员内部类private class PrivateInner {private String innerPrivateField = "内部类私有字段";public String innerPublicField = "内部类公有字段";private void innerPrivateMethod() {System.out.println("内部类私有方法");}public void innerPublicMethod() {System.out.println("内部类公有方法");}}public void accessInnerClass() {// 外部类可以访问内部类的所有成员(包括私有)PrivateInner inner = new PrivateInner();System.out.println("访问内部类私有字段: " + inner.innerPrivateField);System.out.println("访问内部类公有字段: " + inner.innerPublicField);inner.innerPrivateMethod();inner.innerPublicMethod();}// 静态内部类public static class StaticInner {private String staticInnerField = "静态内部类字段";private void staticInnerMethod() {System.out.println("静态内部类私有方法");}}public void accessStaticInner() {StaticInner staticInner = new StaticInner();System.out.println("访问静态内部类私有字段: " + staticInner.staticInnerField);staticInner.staticInnerMethod();}public static void main(String[] args) {OuterAccessInnerDemo demo = new OuterAccessInnerDemo();demo.accessInnerClass();demo.accessStaticInner();}
}

6.3 内部类的继承

// 外部类
class Outer {protected String outerField = "外部类字段";// 内部类public class Inner {protected String innerField = "内部类字段";public void display() {System.out.println("Inner: " + outerField + ", " + innerField);}}
}// 继承内部类需要特殊语法
class SubInner extends Outer.Inner {// 必须通过外部类实例来调用super()public SubInner(Outer outer) {outer.super(); // 特殊语法}@Overridepublic void display() {System.out.println("SubInner: " + outerField + ", " + innerField);}
}// 另一种方式:在外部类内部继承
class ExtendedOuter extends Outer {public class ExtendedInner extends Inner {@Overridepublic void display() {System.out.println("ExtendedInner: " + outerField + ", " + innerField);}}
}public class InnerClassInheritanceDemo {public static void main(String[] args) {// 使用第一种方式Outer outer = new Outer();SubInner subInner = new SubInner(outer);subInner.display();// 使用第二种方式ExtendedOuter extendedOuter = new ExtendedOuter();ExtendedOuter.ExtendedInner extendedInner = extendedOuter.new ExtendedInner();extendedInner.display();}
}

7. 内部类的应用场景

7.1 迭代器模式

import java.util.Iterator;
import java.util.NoSuchElementException;public class MyArrayList<T> implements Iterable<T> {private Object[] elements;private int size = 0;private static final int DEFAULT_CAPACITY = 10;public MyArrayList() {elements = new Object[DEFAULT_CAPACITY];}public void add(T element) {ensureCapacity();elements[size++] = element;}@SuppressWarnings("unchecked")public T get(int index) {if (index >= size || index < 0) {throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);}return (T) elements[index];}public int size() {return size;}private void ensureCapacity() {if (size >= elements.length) {Object[] newElements = new Object[elements.length * 2];System.arraycopy(elements, 0, newElements, 0, size);elements = newElements;}}// 使用成员内部类实现迭代器@Overridepublic Iterator<T> iterator() {return new ArrayListIterator();}// 内部类实现Iterator接口private class ArrayListIterator implements Iterator<T> {private int currentIndex = 0;private int expectedModCount = size; // 简化的并发修改检测@Overridepublic boolean hasNext() {return currentIndex < size;}@Override@SuppressWarnings("unchecked")public T next() {if (!hasNext()) {throw new NoSuchElementException();}if (expectedModCount != size) {throw new RuntimeException("并发修改异常");}return (T) elements[currentIndex++];}@Overridepublic void remove() {if (currentIndex <= 0) {throw new IllegalStateException();}// 移除当前元素int indexToRemove = currentIndex - 1;System.arraycopy(elements, indexToRemove + 1, elements, indexToRemove, size - indexToRemove - 1);size--;currentIndex--;expectedModCount = size;}}// 提供反向迭代器public Iterator<T> reverseIterator() {return new ReverseIterator();}private class ReverseIterator implements Iterator<T> {private int currentIndex = size - 1;@Overridepublic boolean hasNext() {return currentIndex >= 0;}@Override@SuppressWarnings("unchecked")public T next() {if (!hasNext()) {throw new NoSuchElementException();}return (T) elements[currentIndex--];}}
}// 测试迭代器
class IteratorDemo {public static void main(String[] args) {MyArrayList<String> list = new MyArrayList<>();list.add("Apple");list.add("Banana");list.add("Cherry");list.add("Date");System.out.println("正向遍历:");for (String item : list) {System.out.println(item);}System.out.println("\n使用迭代器删除:");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String item = iterator.next();if (item.equals("Banana")) {iterator.remove();System.out.println("删除了: " + item);}}System.out.println("\n删除后的列表:");for (String item : list) {System.out.println(item);}System.out.println("\n反向遍历:");Iterator<String> reverseIter = list.reverseIterator();while (reverseIter.hasNext()) {System.out.println(reverseIter.next());}}
}

7.2 观察者模式

import java.util.ArrayList;
import java.util.List;// 观察者接口
interface Observer {void update(String message);
}// 主题类
public class Subject {private List<Observer> observers = new ArrayList<>();private String state;public void addObserver(Observer observer) {observers.add(observer);System.out.println("添加观察者: " + observer.getClass().getSimpleName());}public void removeObserver(Observer observer) {observers.remove(observer);System.out.println("移除观察者: " + observer.getClass().getSimpleName());}public void setState(String state) {this.state = state;notifyObservers();}public String getState() {return state;}private void notifyObservers() {System.out.println("通知所有观察者,状态变为: " + state);for (Observer observer : observers) {observer.update(state);}}// 使用内部类创建特定类型的观察者public Observer createEmailObserver(String email) {return new EmailObserver(email);}public Observer createSMSObserver(String phone) {return new SMSObserver(phone);}public Observer createLogObserver(String logLevel) {return new LogObserver(logLevel);}// 邮件观察者内部类private class EmailObserver implements Observer {private String email;public EmailObserver(String email) {this.email = email;}@Overridepublic void update(String message) {System.out.println("📧 发送邮件到 " + email + ": " + message);// 模拟发送邮件的延迟try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}// 短信观察者内部类private class SMSObserver implements Observer {private String phone;public SMSObserver(String phone) {this.phone = phone;}@Overridepublic void update(String message) {System.out.println("📱 发送短信到 " + phone + ": " + message);}}// 日志观察者内部类private class LogObserver implements Observer {private String logLevel;public LogObserver(String logLevel) {this.logLevel = logLevel;}@Overridepublic void update(String message) {System.out.println("📝 [" + logLevel + "] 记录日志: " + message + " (时间: " + System.currentTimeMillis() + ")");}}
}// 观察者模式演示
class ObserverPatternDemo {public static void main(String[] args) {Subject subject = new Subject();// 使用内部类创建不同类型的观察者Observer emailObserver = subject.createEmailObserver("admin@example.com");Observer smsObserver = subject.createSMSObserver("13888888888");Observer logObserver = subject.createLogObserver("INFO");// 添加观察者subject.addObserver(emailObserver);subject.addObserver(smsObserver);subject.addObserver(logObserver);System.out.println("\n--- 第一次状态变更 ---");subject.setState("系统启动成功");System.out.println("\n--- 第二次状态变更 ---");subject.setState("用户登录");System.out.println("\n--- 移除SMS观察者后 ---");subject.removeObserver(smsObserver);subject.setState("数据备份完成");// 使用匿名内部类创建临时观察者System.out.println("\n--- 添加临时观察者 ---");Observer tempObserver = new Observer() {@Overridepublic void update(String message) {System.out.println("🔔 临时通知: " + message);}};subject.addObserver(tempObserver);subject.setState("系统维护开始");}
}

7.3 工厂模式与内部类

// 产品接口
interface Vehicle {void start();void stop();String getType();
}// 工厂类
public class VehicleFactory {// 车辆类型枚举public enum VehicleType {CAR, MOTORCYCLE, TRUCK}// 使用静态内部类实现不同的车辆public static class Car implements Vehicle {private String model;public Car(String model) {this.model = model;}@Overridepublic void start() {System.out.println(model + " 汽车启动:插入钥匙,启动引擎");}@Overridepublic void stop() {System.out.println(model + " 汽车熄火:关闭引擎,拔出钥匙");}@Overridepublic String getType() {return "汽车";}}public static class Motorcycle implements Vehicle {private String brand;public Motorcycle(String brand) {this.brand = brand;}@Overridepublic void start() {System.out.println(brand + " 摩托车启动:踩启动杆,发动引擎");}@Overridepublic void stop() {System.out.println(brand + " 摩托车熄火:关闭油门,停止引擎");}@Overridepublic String getType() {return "摩托车";}}public static class Truck implements Vehicle {private String capacity;public Truck(String capacity) {this.capacity = capacity;}@Overridepublic void start() {System.out.println(capacity + " 卡车启动:预热引擎,启动车辆");}@Overridepublic void stop() {System.out.println(capacity + " 卡车停车:停车熄火,拉手刹");}@Overridepublic String getType() {return "卡车";}}// 工厂方法public static Vehicle createVehicle(VehicleType type, String specification) {switch (type) {case CAR:return new Car(specification);case MOTORCYCLE:return new Motorcycle(specification);case TRUCK:return new Truck(specification);default:throw new IllegalArgumentException("不支持的车辆类型: " + type);}}// 创建车辆列表public static List<Vehicle> createVehicleFleet() {List<Vehicle> fleet = new ArrayList<>();fleet.add(createVehicle(VehicleType.CAR, "本田雅阁"));fleet.add(createVehicle(VehicleType.CAR, "丰田凯美瑞"));fleet.add(createVehicle(VehicleType.MOTORCYCLE, "雅马哈"));fleet.add(createVehicle(VehicleType.TRUCK, "10吨"));return fleet;}
}// 车队管理类
class FleetManager {private List<Vehicle> vehicles;public FleetManager() {this.vehicles = VehicleFactory.createVehicleFleet();}public void startAllVehicles() {System.out.println("=== 启动所有车辆 ===");for (Vehicle vehicle : vehicles) {vehicle.start();}}public void stopAllVehicles() {System.out.println("\n=== 停止所有车辆 ===");for (Vehicle vehicle : vehicles) {vehicle.stop();}}public void showFleetInfo() {System.out.println("\n=== 车队信息 ===");for (int i = 0; i < vehicles.size(); i++) {Vehicle vehicle = vehicles.get(i);System.out.println((i + 1) + ". " + vehicle.getType());}}public static void main(String[] args) {FleetManager manager = new FleetManager();manager.showFleetInfo();manager.startAllVehicles();manager.stopAllVehicles();}
}

8. 最佳实践

8.1 内部类使用准则

public class BestPracticesDemo {// ✅ 好的实践:使用私有内部类隐藏实现细节private class GoodInnerClass {private void helperMethod() {// 只在外部类内部使用的辅助方法}}// ❌ 避免:公有内部类暴露不必要的实现细节public class BadInnerClass {public void exposedMethod() {// 这个方法可能不应该被外部访问}}// ✅ 好的实践:内部类名称要有意义private class DatabaseConnectionPool {// 清晰的类名表达了其用途}// ❌ 避免:无意义的内部类名称private class InnerClass1 {// 不清楚这个类的用途}// ✅ 好的实践:当内部类不需要访问外部类实例时,使用静态内部类public static class UtilityHelper {public static void doSomething() {// 不需要外部类实例,应该是静态的}}// ❌ 避免:不必要的非静态内部类public class UnnecessaryInnerClass {public void doSomething() {// 如果不需要访问外部类成员,应该是静态的}}
}

8.2 性能考虑

public class PerformanceConsiderations {private String outerField = "外部字段";// ✅ 静态内部类:不持有外部类引用,内存效率更高public static class EfficientStaticInner {public void process() {// 不会持有外部类引用}}// ⚠️ 非静态内部类:持有外部类引用,可能导致内存泄漏public class NonStaticInner {public void process() {// 隐式持有外部类引用System.out.println(outerField);}}// 演示内存泄漏风险public Runnable createTask() {return new Runnable() {@Overridepublic void run() {// 匿名内部类持有外部类引用// 如果这个Runnable被长期持有,外部类也不会被GCSystem.out.println("任务执行中...");}};}// ✅ 更好的方式:使用静态内部类public static Runnable createEfficientTask(final String message) {return new Runnable() {@Overridepublic void run() {System.out.println(message);}};}// 演示内存使用情况public static void memoryDemo() {PerformanceConsiderations outer = new PerformanceConsiderations();// 创建多个内部类实例List<Object> instances = new ArrayList<>();for (int i = 0; i < 10000; i++) {// 非静态内部类,每个都持有外部类引用instances.add(outer.new NonStaticInner());}// 即使外部类不再需要,但因为内部类实例持有引用,不会被GCouter = null; // 外部类引用置空System.gc(); // 建议垃圾回收System.out.println("创建了 " + instances.size() + " 个内部类实例");// 在实际应用中,这可能导致内存泄漏}
}

8.3 线程安全考虑

public class ThreadSafetyDemo {private int count = 0;private final Object lock = new Object();// ✅ 线程安全的内部类public class ThreadSafeCounter {public void increment() {synchronized (lock) {count++;}}public void decrement() {synchronized (lock) {count--;}}public int getCount() {synchronized (lock) {return count;}}}// ❌ 非线程安全的内部类public class UnsafeCounter {public void increment() {count++; // 不安全的操作}public int getCount() {return count; // 可能读到不一致的值}}// 演示线程安全问题public static void threadSafetyTest() {ThreadSafetyDemo demo = new ThreadSafetyDemo();ThreadSafeCounter safeCounter = demo.new ThreadSafeCounter();UnsafeCounter unsafeCounter = demo.new UnsafeCounter();// 创建多个线程同时操作计数器ExecutorService executor = Executors.newFixedThreadPool(10);CountDownLatch latch = new CountDownLatch(2);// 测试线程安全的计数器executor.submit(() -> {for (int i = 0; i < 1000; i++) {safeCounter.increment();}System.out.println("线程安全计数器结果: " + safeCounter.getCount());latch.countDown();});// 重置计数器demo.count = 0;// 测试非线程安全的计数器executor.submit(() -> {for (int i = 0; i < 1000; i++) {unsafeCounter.increment();}System.out.println("非线程安全计数器结果: " + unsafeCounter.getCount());latch.countDown();});try {latch.await();} catch (InterruptedException e) {Thread.currentThread().interrupt();}executor.shutdown();}
}

8.4 代码组织和设计原则

// ✅ 好的设计:内部类与外部类紧密相关
public class FileProcessor {private String filePath;public FileProcessor(String filePath) {this.filePath = filePath;}// 内部类:文件读取策略public abstract class ReadStrategy {protected abstract String readContent();public final void process() {String content = readContent();System.out.println("处理文件内容: " + content.length() + " 字符");}}// 具体的读取策略public class TextFileStrategy extends ReadStrategy {@Overrideprotected String readContent() {return "模拟读取文本文件: " + filePath;}}public class BinaryFileStrategy extends ReadStrategy {@Overrideprotected String readContent() {return "模拟读取二进制文件: " + filePath;}}// 工厂方法public ReadStrategy createStrategy(String fileType) {switch (fileType.toLowerCase()) {case "txt":return new TextFileStrategy();case "bin":return new BinaryFileStrategy();default:throw new IllegalArgumentException("不支持的文件类型: " + fileType);}}
}// ✅ 好的设计:使用内部类实现回调
public class NetworkClient {public interface ResponseCallback {void onSuccess(String response);void onError(String error);}public void sendRequest(String url, ResponseCallback callback) {// 模拟网络请求new Thread(() -> {try {Thread.sleep(1000); // 模拟网络延迟if (url.startsWith("https://")) {callback.onSuccess("请求成功: " + url);} else {callback.onError("不安全的URL: " + url);}} catch (InterruptedException e) {callback.onError("请求被中断");}}).start();}// 使用内部类提供默认回调实现public static class DefaultCallback implements ResponseCallback {@Overridepublic void onSuccess(String response) {System.out.println("默认成功处理: " + response);}@Overridepublic void onError(String error) {System.err.println("默认错误处理: " + error);}}// 使用内部类提供日志回调实现public static class LoggingCallback implements ResponseCallback {private final String prefix;public LoggingCallback(String prefix) {this.prefix = prefix;}@Overridepublic void onSuccess(String response) {System.out.println("[" + prefix + "] 成功: " + response);}@Overridepublic void onError(String error) {System.out.println("[" + prefix + "] 错误: " + error);}}
}// 使用示例
class DesignPrinciplesDemo {public static void main(String[] args) throws InterruptedException {// 文件处理示例FileProcessor processor = new FileProcessor("example.txt");FileProcessor.ReadStrategy strategy = processor.createStrategy("txt");strategy.process();// 网络请求示例NetworkClient client = new NetworkClient();// 使用默认回调client.sendRequest("https://api.example.com", new NetworkClient.DefaultCallback());// 使用日志回调client.sendRequest("http://api.example.com", new NetworkClient.LoggingCallback("API"));// 使用匿名内部类client.sendRequest("https://secure.example.com", new NetworkClient.ResponseCallback() {@Overridepublic void onSuccess(String response) {System.out.println("自定义成功处理: " + response);}@Overridepublic void onError(String error) {System.out.println("自定义错误处理: " + error);}});// 等待异步操作完成Thread.sleep(2000);}
} 

9. 常见问题和解决方案

9.1 编译错误问题

public class CompilationErrorsDemo {private String outerField = "外部字段";// 问题1:在静态内部类中访问非静态成员public static class StaticInnerProblem {public void problemMethod() {// System.out.println(outerField); // 编译错误!// 解决方案:传递外部类实例或使用静态成员}// 正确的方式public void correctMethod(CompilationErrorsDemo outer) {System.out.println(outer.outerField);}}// 问题2:局部内部类访问非final变量public void localInnerProblem() {String localVar = "局部变量";// localVar = "修改"; // 如果修改了,下面的内部类会编译错误class LocalInner {public void access() {System.out.println(localVar); // 只能访问effectively final变量}}new LocalInner().access();}// 问题3:内部类构造函数问题public class InnerWithConstructor {private String name;// 正确:内部类可以有参数构造函数public InnerWithConstructor(String name) {this.name = name;}public void display() {System.out.println("外部字段: " + outerField);System.out.println("内部字段: " + name);}}public static void demonstrateProblems() {CompilationErrorsDemo outer = new CompilationErrorsDemo();// 正确创建内部类实例InnerWithConstructor inner = outer.new InnerWithConstructor("内部类实例");inner.display();// 正确使用静态内部类StaticInnerProblem.correctMethod(outer);}
}

9.2 内存泄漏问题

import java.util.ArrayList;
import java.util.List;public class MemoryLeakDemo {private List<String> data = new ArrayList<>();private String className = this.getClass().getSimpleName();// 问题:匿名内部类导致内存泄漏public Runnable createLeakyTask() {// 添加一些数据模拟大对象for (int i = 0; i < 10000; i++) {data.add("数据项 " + i);}return new Runnable() {@Overridepublic void run() {// 这个匿名内部类持有外部类引用// 即使只使用className,整个外部类(包括data)都不会被GCSystem.out.println("任务执行: " + className);}};}// 解决方案1:使用静态内部类public static Runnable createNonLeakyTask(String className) {return new Runnable() {@Overridepublic void run() {System.out.println("任务执行: " + className);}};}// 解决方案2:在方法结束前释放大对象public Runnable createOptimizedTask() {String localClassName = this.className; // 复制需要的数据data.clear(); // 及时释放大对象return new Runnable() {@Overridepublic void run() {System.out.println("任务执行: " + localClassName);}};}// 内存泄漏检测工具方法public static void memoryLeakTest() {List<Runnable> tasks = new ArrayList<>();System.out.println("创建可能导致内存泄漏的任务...");for (int i = 0; i < 100; i++) {MemoryLeakDemo demo = new MemoryLeakDemo();tasks.add(demo.createLeakyTask()); // 每个任务都持有demo引用}// 强制垃圾回收System.gc();// 获取内存使用情况Runtime runtime = Runtime.getRuntime();long usedMemory = runtime.totalMemory() - runtime.freeMemory();System.out.println("使用内存: " + usedMemory / 1024 / 1024 + " MB");// 清理任务tasks.clear();System.gc();usedMemory = runtime.totalMemory() - runtime.freeMemory();System.out.println("清理后内存: " + usedMemory / 1024 / 1024 + " MB");}
}

9.3 序列化问题

import java.io.*;public class SerializationDemo implements Serializable {private static final long serialVersionUID = 1L;private String outerData = "外部类数据";// 问题:非静态内部类的序列化public class NonStaticInner implements Serializable {private static final long serialVersionUID = 2L;private String innerData = "内部类数据";public void display() {System.out.println("外部: " + outerData + ", 内部: " + innerData);}}// 解决方案:静态内部类可以正常序列化public static class StaticInner implements Serializable {private static final long serialVersionUID = 3L;private String innerData = "静态内部类数据";public void display() {System.out.println("静态内部: " + innerData);}}public static void serializationTest() {try {SerializationDemo outer = new SerializationDemo();// 序列化静态内部类(成功)StaticInner staticInner = new StaticInner();ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(staticInner);oos.close();// 反序列化ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);StaticInner deserializedStatic = (StaticInner) ois.readObject();deserializedStatic.display();ois.close();System.out.println("静态内部类序列化成功");// 序列化非静态内部类(需要特殊处理)NonStaticInner nonStaticInner = outer.new NonStaticInner();baos = new ByteArrayOutputStream();oos = new ObjectOutputStream(baos);oos.writeObject(nonStaticInner); // 会同时序列化外部类oos.close();bais = new ByteArrayInputStream(baos.toByteArray());ois = new ObjectInputStream(bais);NonStaticInner deserializedNonStatic = (NonStaticInner) ois.readObject();deserializedNonStatic.display();ois.close();System.out.println("非静态内部类序列化成功(包含外部类)");} catch (Exception e) {System.err.println("序列化失败: " + e.getMessage());e.printStackTrace();}}
}

10. Lambda表达式与内部类对比

10.1 从匿名内部类到Lambda表达式

import java.util.*;
import java.util.function.*;public class LambdaVsInnerClassDemo {public void comparisonDemo() {List<String> names = Arrays.asList("张三", "李四", "王五", "赵六");// 1. 使用匿名内部类实现ComparatorSystem.out.println("=== 匿名内部类方式 ===");Collections.sort(names, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s1.length() - s2.length(); // 按长度排序}});System.out.println("排序结果: " + names);// 2. 使用Lambda表达式System.out.println("\n=== Lambda表达式方式 ===");names = Arrays.asList("张三", "李四", "王五", "赵六"); // 重置Collections.sort(names, (s1, s2) -> s1.length() - s2.length());System.out.println("排序结果: " + names);// 3. 使用方法引用System.out.println("\n=== 方法引用方式 ===");names = Arrays.asList("张三", "李四", "王五", "赵六"); // 重置Collections.sort(names, Comparator.comparing(String::length));System.out.println("排序结果: " + names);}public void functionalInterfaceDemo() {// 匿名内部类方式Runnable task1 = new Runnable() {@Overridepublic void run() {System.out.println("匿名内部类任务执行");}};// Lambda表达式方式Runnable task2 = () -> System.out.println("Lambda任务执行");// 执行任务task1.run();task2.run();// Predicate示例Predicate<String> isEmpty1 = new Predicate<String>() {@Overridepublic boolean test(String s) {return s.isEmpty();}};Predicate<String> isEmpty2 = String::isEmpty; // 方法引用System.out.println("空字符串测试1: " + isEmpty1.test(""));System.out.println("空字符串测试2: " + isEmpty2.test(""));}// 何时使用匿名内部类 vs Lambda表达式public void whenToUseWhat() {// 使用匿名内部类的场景:// 1. 需要实现多个方法的接口ActionListener listener = new ActionListener() {private int clickCount = 0;@Overridepublic void actionPerformed(ActionEvent e) {clickCount++;System.out.println("按钮点击了 " + clickCount + " 次");}// 可以添加额外的方法和字段public int getClickCount() {return clickCount;}};// 2. 需要访问和修改外部变量(使用字段)Counter counter = new Counter();// 使用Lambda表达式的场景:// 1. 函数式接口(只有一个抽象方法)List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 过滤numbers.stream().filter(n -> n % 2 == 0) // Lambda更简洁.forEach(System.out::println);// 2. 简单的操作Optional<String> optional = Optional.of("Hello");optional.ifPresent(s -> System.out.println("值: " + s));}// 辅助类interface ActionListener {void actionPerformed(ActionEvent e);}static class ActionEvent {// 模拟事件类}static class Counter {private int count = 0;public void increment() {count++;}public int getCount() {return count;}}public static void main(String[] args) {LambdaVsInnerClassDemo demo = new LambdaVsInnerClassDemo();demo.comparisonDemo();demo.functionalInterfaceDemo();demo.whenToUseWhat();}
}

10.2 性能对比

import java.util.function.Function;public class PerformanceComparison {private static final int ITERATIONS = 1000000;public static void performanceTest() {// 匿名内部类性能测试long startTime = System.nanoTime();for (int i = 0; i < ITERATIONS; i++) {Function<String, Integer> lengthFunction = new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return s.length();}};lengthFunction.apply("测试字符串");}long anonymousTime = System.nanoTime() - startTime;// Lambda表达式性能测试startTime = System.nanoTime();for (int i = 0; i < ITERATIONS; i++) {Function<String, Integer> lengthFunction = s -> s.length();lengthFunction.apply("测试字符串");}long lambdaTime = System.nanoTime() - startTime;// 方法引用性能测试startTime = System.nanoTime();for (int i = 0; i < ITERATIONS; i++) {Function<String, Integer> lengthFunction = String::length;lengthFunction.apply("测试字符串");}long methodRefTime = System.nanoTime() - startTime;System.out.println("性能测试结果 (" + ITERATIONS + " 次迭代):");System.out.println("匿名内部类: " + anonymousTime / 1000000.0 + " ms");System.out.println("Lambda表达式: " + lambdaTime / 1000000.0 + " ms");System.out.println("方法引用: " + methodRefTime / 1000000.0 + " ms");// 内存使用测试memoryUsageTest();}private static void memoryUsageTest() {Runtime runtime = Runtime.getRuntime();// 测试匿名内部类内存使用runtime.gc();long beforeAnonymous = runtime.totalMemory() - runtime.freeMemory();Function<String, Integer>[] anonymousFunctions = new Function[10000];for (int i = 0; i < anonymousFunctions.length; i++) {anonymousFunctions[i] = new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return s.length();}};}long afterAnonymous = runtime.totalMemory() - runtime.freeMemory();// 测试Lambda表达式内存使用runtime.gc();long beforeLambda = runtime.totalMemory() - runtime.freeMemory();Function<String, Integer>[] lambdaFunctions = new Function[10000];for (int i = 0; i < lambdaFunctions.length; i++) {lambdaFunctions[i] = s -> s.length();}long afterLambda = runtime.totalMemory() - runtime.freeMemory();System.out.println("\n内存使用测试:");System.out.println("匿名内部类: " + (afterAnonymous - beforeAnonymous) / 1024 + " KB");System.out.println("Lambda表达式: " + (afterLambda - beforeLambda) / 1024 + " KB");}public static void main(String[] args) {performanceTest();}
}

11. 高级主题

11.1 内部类的反射操作

import java.lang.reflect.*;public class InnerClassReflectionDemo {private String outerField = "外部字段";public class InnerClass {private String innerField = "内部字段";public void innerMethod() {System.out.println("内部类方法执行");}}public static class StaticInnerClass {private String staticInnerField = "静态内部字段";public void staticInnerMethod() {System.out.println("静态内部类方法执行");}}public static void reflectionDemo() {try {// 获取外部类Class<?> outerClass = InnerClassReflectionDemo.class;System.out.println("外部类: " + outerClass.getName());// 获取所有内部类Class<?>[] innerClasses = outerClass.getDeclaredClasses();System.out.println("\n内部类列表:");for (Class<?> innerClass : innerClasses) {System.out.println("- " + innerClass.getName());System.out.println("  是否静态: " + Modifier.isStatic(innerClass.getModifiers()));System.out.println("  是否公有: " + Modifier.isPublic(innerClass.getModifiers()));}// 操作非静态内部类System.out.println("\n=== 操作非静态内部类 ===");Class<?> innerClass = outerClass.getDeclaredClasses()[0]; // InnerClass// 创建外部类实例Constructor<?> outerConstructor = outerClass.getConstructor();Object outerInstance = outerConstructor.newInstance();// 创建内部类实例(需要外部类实例)Constructor<?> innerConstructor = innerClass.getDeclaredConstructor(outerClass);Object innerInstance = innerConstructor.newInstance(outerInstance);// 调用内部类方法Method innerMethod = innerClass.getDeclaredMethod("innerMethod");innerMethod.invoke(innerInstance);// 访问内部类私有字段Field innerField = innerClass.getDeclaredField("innerField");innerField.setAccessible(true);String fieldValue = (String) innerField.get(innerInstance);System.out.println("内部类私有字段值: " + fieldValue);// 操作静态内部类System.out.println("\n=== 操作静态内部类 ===");Class<?> staticInnerClass = null;for (Class<?> cls : innerClasses) {if (cls.getSimpleName().equals("StaticInnerClass")) {staticInnerClass = cls;break;}}if (staticInnerClass != null) {// 创建静态内部类实例(不需要外部类实例)Constructor<?> staticConstructor = staticInnerClass.getConstructor();Object staticInstance = staticConstructor.newInstance();// 调用静态内部类方法Method staticMethod = staticInnerClass.getDeclaredMethod("staticInnerMethod");staticMethod.invoke(staticInstance);// 访问静态内部类私有字段Field staticField = staticInnerClass.getDeclaredField("staticInnerField");staticField.setAccessible(true);String staticFieldValue = (String) staticField.get(staticInstance);System.out.println("静态内部类私有字段值: " + staticFieldValue);}// 检查封闭类System.out.println("\n=== 封闭类信息 ===");Class<?> enclosingClass = innerClass.getEnclosingClass();System.out.println("内部类的封闭类: " + enclosingClass.getName());Method enclosingMethod = innerClass.getEnclosingMethod();Constructor<?> enclosingConstructor = innerClass.getEnclosingConstructor();System.out.println("封闭方法: " + enclosingMethod);System.out.println("封闭构造器: " + enclosingConstructor);} catch (Exception e) {e.printStackTrace();}}public void demonstrateLocalClass() {class LocalClass {public void localMethod() {System.out.println("局部类方法");}}// 局部类的反射信息Class<?> localClass = LocalClass.class;System.out.println("\n=== 局部类信息 ===");System.out.println("局部类名: " + localClass.getName());System.out.println("是否局部类: " + localClass.isLocalClass());System.out.println("是否匿名类: " + localClass.isAnonymousClass());System.out.println("封闭方法: " + localClass.getEnclosingMethod().getName());}public static void main(String[] args) {reflectionDemo();InnerClassReflectionDemo demo = new InnerClassReflectionDemo();demo.demonstrateLocalClass();}
}

11.2 内部类的字节码分析

// 这个类展示内部类编译后的字节码特征
public class BytecodeAnalysisDemo {private String outerField = "外部字段";// 成员内部类public class MemberInner {public void accessOuter() {System.out.println(outerField); // 编译器会生成合成方法来访问}}// 静态内部类public static class StaticInner {public void method() {System.out.println("静态内部类方法");}}// 局部内部类public void createLocalClass() {final String localVar = "局部变量";class LocalInner {public void access() {System.out.println(localVar); // 编译器会生成字段来保存局部变量}}new LocalInner().access();}// 匿名内部类public Runnable createAnonymousClass() {return new Runnable() {@Overridepublic void run() {System.out.println(outerField); // 持有外部类引用}};}/** 编译后的字节码特征:* * 1. 成员内部类 MemberInner:*    - 编译为: BytecodeAnalysisDemo$MemberInner.class*    - 包含一个指向外部类的合成字段: this$0*    - 外部类会生成合成方法来提供对私有成员的访问* * 2. 静态内部类 StaticInner:*    - 编译为: BytecodeAnalysisDemo$StaticInner.class*    - 不包含指向外部类的引用* * 3. 局部内部类:*    - 编译为: BytecodeAnalysisDemo$1LocalInner.class*    - 包含捕获的局部变量作为final字段* * 4. 匿名内部类:*    - 编译为: BytecodeAnalysisDemo$1.class (数字递增)*    - 包含指向外部类的合成字段*/// 演示合成字段和方法的存在public static void demonstrateSyntheticElements() {try {// 检查内部类的合成字段Class<?> memberInnerClass = Class.forName("BytecodeAnalysisDemo$MemberInner");Field[] fields = memberInnerClass.getDeclaredFields();System.out.println("MemberInner类的字段:");for (Field field : fields) {System.out.println("- " + field.getName() + " (合成: " + field.isSynthetic() + ")");}// 检查外部类的合成方法Class<?> outerClass = BytecodeAnalysisDemo.class;Method[] methods = outerClass.getDeclaredMethods();System.out.println("\n外部类的合成方法:");for (Method method : methods) {if (method.isSynthetic()) {System.out.println("- " + method.getName() + " (参数: " + method.getParameterCount() + ")");}}} catch (ClassNotFoundException e) {System.err.println("类未找到: " + e.getMessage());}}public static void main(String[] args) {demonstrateSyntheticElements();BytecodeAnalysisDemo demo = new BytecodeAnalysisDemo();demo.createLocalClass();Runnable task = demo.createAnonymousClass();task.run();}
}

11.3 内部类与设计模式的深度结合

// 状态模式与内部类的结合
public class StatePatternWithInnerClasses {// 状态接口public interface State {void handle(Context context);String getStateName();}// 上下文类public static class Context {private State currentState;private String data = "";public Context() {currentState = new IdleState(this);}public void setState(State state) {System.out.println("状态转换: " + currentState.getStateName() + " -> " + state.getStateName());this.currentState = state;}public void request() {currentState.handle(this);}public String getData() { return data; }public void setData(String data) { this.data = data; }}// 使用静态内部类实现状态public static class IdleState implements State {private Context context;public IdleState(Context context) {this.context = context;}@Overridepublic void handle(Context context) {System.out.println("空闲状态:开始处理请求");context.setData("处理中...");context.setState(new ProcessingState(context));}@Overridepublic String getStateName() {return "空闲状态";}}public static class ProcessingState implements State {private Context context;public ProcessingState(Context context) {this.context = context;}@Overridepublic void handle(Context context) {System.out.println("处理状态:正在处理数据 - " + context.getData());context.setData("处理完成");context.setState(new CompletedState(context));}@Overridepublic String getStateName() {return "处理状态";}}public static class CompletedState implements State {private Context context;public CompletedState(Context context) {this.context = context;}@Overridepublic void handle(Context context) {System.out.println("完成状态:处理结果 - " + context.getData());context.setData("");context.setState(new IdleState(context));}@Overridepublic String getStateName() {return "完成状态";}}public static void main(String[] args) {Context context = new Context();// 执行状态转换for (int i = 0; i < 3; i++) {System.out.println("\n=== 第" + (i + 1) + "轮处理 ===");context.request(); // 空闲 -> 处理context.request(); // 处理 -> 完成context.request(); // 完成 -> 空闲}}
}

12. 总结

12.1 内部类知识点总结

通过这个详细的教程,我们深入学习了Java内部类的方方面面:

🎯 四种内部类类型:

  1. 成员内部类

    • 可以访问外部类的所有成员
    • 持有外部类的隐式引用
    • 不能定义静态成员(除静态常量外)
    • 适用于需要紧密耦合的辅助类
  2. 静态内部类

    • 不持有外部类引用,内存效率更高
    • 只能访问外部类的静态成员
    • 可以定义静态和非静态成员
    • 适用于工具类、建造者模式等场景
  3. 局部内部类

    • 定义在方法内部,作用域仅限于该方法
    • 可以访问final或effectively final的局部变量
    • 适用于实现局部的特定逻辑
  4. 匿名内部类

    • 没有类名,通常用于创建只使用一次的类实例
    • 简化代码,特别适合事件处理和回调
    • Lambda表达式是其现代化替代方案

💡 关键设计原则:

  • 封装性:使用适当的访问修饰符控制内部类的可见性
  • 内聚性:内部类应该与外部类逻辑相关
  • 性能考虑:静态内部类优于非静态内部类(当不需要外部类引用时)
  • 内存管理:注意匿名内部类可能导致的内存泄漏

🚀 实际应用场景:

  • 迭代器模式:ArrayList的内部Iterator实现
  • 观察者模式:事件监听器的实现
  • 建造者模式:复杂对象的构建
  • 状态模式:状态机的实现
  • 回调机制:异步处理和事件响应

12.2 最佳实践建议

  1. 选择合适的内部类类型

    • 需要访问外部类实例 → 成员内部类
    • 不需要外部类实例 → 静态内部类
    • 只在方法内使用 → 局部内部类
    • 简单的一次性实现 → 匿名内部类或Lambda
  2. 注意内存泄漏

    • 匿名内部类和成员内部类持有外部类引用
    • 长期持有内部类实例可能阻止外部类被垃圾回收
    • 适当时使用静态内部类或将引用置空
  3. 考虑性能影响

    • 静态内部类创建和访问速度更快
    • Lambda表达式在某些情况下比匿名内部类更高效
    • 避免在循环中创建大量内部类实例
  4. 保持代码可读性

    • 内部类名称要有意义
    • 避免过深的嵌套
    • 考虑将复杂的内部类提取为独立的类

12.3 学习建议

  1. 实践练习:多写代码,在实际项目中应用内部类
  2. 阅读源码:研究JDK中内部类的使用,如集合类的实现
  3. 性能测试:对比不同内部类类型的性能差异
  4. 设计模式:学习内部类在各种设计模式中的应用
  5. 现代Java:了解Lambda表达式和函数式编程对内部类使用的影响

🌟 记住关键点:

  • 内部类是Java面向对象编程的强大特性
  • 正确使用可以提高代码的封装性和可维护性
  • 需要权衡便利性与性能、内存使用的关系
  • 现代Java开发中要结合Lambda表达式的使用
  • 始终考虑代码的可读性和维护性

通过掌握内部类,您将能够写出更加优雅、高效的Java代码,并更好地理解许多Java框架和库的实现原理。继续练习和探索,内部类将成为您Java编程技能的重要组成部分!

继续学习的方向:

  • Java 8+ 函数式编程特性
  • 设计模式的深入学习
  • Java并发编程中的内部类应用
http://www.xdnf.cn/news/10605.html

相关文章:

  • 06.MySQL数据库操作详解
  • Retrievers检索器+RAG文档助手项目实战
  • 字符串加解密
  • 配置刷新技术
  • 【Python 进阶3】常见的 call 和 forward 区别
  • JavaSE 字符串:深入解析 String、StringBuilder与 StringBuffer
  • 第十章:Next的Seo实践
  • 力扣HOT100之多维动态规划:62. 不同路径
  • C. Basketball Exercise
  • Vue-6-前端框架Vue之基于Plotly.js绘制曲线
  • 3,信号与槽机制
  • BUUCTF[ACTF2020 新生赛]Include 1题解
  • NVM,Node.Js 管理工具
  • 【Delphi】接收windows文件夹中文件拖拽
  • (Python网络爬虫);抓取B站404页面小漫画
  • Python-matplotlib库之核心对象
  • 设计模式——备忘录设计模式(行为型)
  • Kotlin 中 companion object 扩展函数详解
  • Java连接Redis和基础操作命令
  • 【Linux】Ubuntu 20.04 英文系统显示中文字体异常
  • 什么是线程上下文切换?
  • 【SpringBoot】| 接口架构风格—RESTful
  • 概率统计:AI大模型的数学支柱
  • Linux--进程概念
  • 【redis实战篇】第七天
  • 03- javascript的运行原理
  • 启动metastore时报错MetaException(message:Version information not found in metastore
  • 海底三维可视化平台
  • 使用Python进行函数作画
  • azure devops 系列 - 常用的task