83. Java 何时使用嵌套类、局部类、匿名类和 Lambda 表达式?

48 阅读4分钟

83. Java 何时使用嵌套类、局部类、匿名类和 Lambda 表达式?

在 Java 中,我们可以使用 嵌套类(Nested Class)、局部类(Local Class)、匿名类(Anonymous Class)和 Lambda 表达式 来封装逻辑,提高代码可读性和可维护性。但在不同的场景下,应该选择不同的方案


1️⃣ 什么是嵌套类、局部类、匿名类和 Lambda?

类型适用场景访问范围是否需要类名
嵌套类(Nested Class)逻辑上属于外部类的一部分依赖于是否 static✅ 需要
局部类(Local Class)仅在某个方法/代码块中使用仅在方法/代码块中可见✅ 需要
匿名类(Anonymous Class)只需要一个实例,且不想命名仅在定义处可见❌ 不需要
Lambda 表达式替代匿名类,用于函数式接口仅在定义处可见❌ 不需要

2️⃣ 何时使用哪种类型?

✅ 嵌套类(Nested Class)

  • 当一个类 逻辑上属于另一个类,但不需要访问外部类的方法或实例变量时,可以使用 静态嵌套类(Static Nested Class)
  • 如果需要访问外部类的非 static 成员,则使用 非静态嵌套类(Inner Class)

💡 示例:使用静态嵌套类

public class OuterClass {
    private String outerField = "Outer";

    // 静态嵌套类
    public static class StaticNestedClass {
        public void display() {
            System.out.println("Inside Static Nested Class");
        }
    }

    // 非静态嵌套类(内部类)
    public class InnerClass {
        public void display() {
            System.out.println("Outer field: " + outerField);
        }
    }
}

public class NestedClassTest {
    public static void main(String[] args) {
        // 访问静态嵌套类
        OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
        nested.display();

        // 访问内部类
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.display();
    }
}

💡 使用场景静态嵌套类 适用于不依赖外部类实例的场景(如 Map.Entry)。 ✅ 内部类 适用于需要访问外部类的实例变量和方法的场景。


✅ 局部类(Local Class)

  • 当类的作用范围仅限于某个方法内部,且需要多次创建实例,可以使用局部类。
  • 局部类可以访问外部方法的 final 或 effectively final 变量

💡 示例

public class LocalClassExample {
    public void printMessage() {
        final String localVariable = "Hello from Local Class";

        // 局部类
        class LocalPrinter {
            public void print() {
                System.out.println(localVariable);
            }
        }

        LocalPrinter printer = new LocalPrinter();
        printer.print();
    }

    public static void main(String[] args) {
        new LocalClassExample().printMessage();
    }
}

💡 使用场景当方法中需要创建多个对象,且对象逻辑复杂,使用局部类。 ❌ 如果只需要一个对象,匿名类或 Lambda 更合适


✅ 匿名类(Anonymous Class)

  • 适用于只创建一个实例,并且不需要类名的场景
  • 适用于继承类或实现接口,但不想单独创建类的情况

💡 示例

import java.util.Timer;
import java.util.TimerTask;

public class AnonymousClassExample {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Task executed!");
            }
        }, 2000); // 2秒后执行
    }
}

💡 使用场景当只需要实现一次接口或扩展类,并且不想创建单独的类。 ❌ 如果代码复杂,需要多个方法,局部类更合适。 ✅ 适用于 GUI 事件监听ActionListener)。


✅ Lambda 表达式

  • Lambda 是匿名类的简化版,仅适用于函数式接口(@FunctionalInterface
  • 适用于“行为”传递的场景,如回调、排序、事件处理

💡 示例

import java.util.Arrays;
import java.util.List;

public class LambdaExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // 使用 Lambda 遍历列表
        names.forEach(name -> System.out.println(name));
    }
}

💡 使用场景如果匿名类只实现一个方法,并且不需要额外字段或方法,Lambda 是最佳选择。 ✅ 适用于回调、流式处理(Stream API。 ❌ 如果需要多个方法或状态,匿名类或局部类更合适


3️⃣ 何时使用哪种方案?(总结)

场景推荐使用
逻辑上属于外部类的一部分,但不需要访问外部类成员静态嵌套类
逻辑上属于外部类的一部分,需要访问外部类实例变量非静态嵌套类(内部类)
仅在方法内部使用,需要多次创建实例局部类
只需要创建一个实例,不需要类名匿名类
实现单个方法,不需要额外状态Lambda 表达式

4️⃣ 代码示例对比

✅ 嵌套类

class Outer {
    static class StaticNested { void method() {} }
    class Inner { void method() {} }
}

💡 适用于:需要更广泛的作用域,但仍然逻辑上属于外部类的情况。


✅ 局部类

public void method() {
    class LocalClass { void method() {} }
    LocalClass obj = new LocalClass();
}

💡 适用于:只在方法内使用,且可能需要多个实例。


✅ 匿名类

Runnable r = new Runnable() {
    public void run() { System.out.println("Running..."); }
};

💡 适用于:一次性使用,且代码较短的情况。


✅ Lambda

Runnable r = () -> System.out.println("Running...");

💡 适用于:实现单个方法的函数式接口。


5️⃣ 结论

嵌套类:如果类是外部类逻辑的一部分,且需要更广泛的作用域,使用它。 ✅ 局部类:如果类仅在方法内部使用,且需要多个实例,使用它。 ✅ 匿名类:如果只需要一个实例,且不需要类名,使用它。 ✅ Lambda:如果只实现一个方法,且不需要额外字段或方法,使用它。

💡 最重要的原则代码要清晰、简洁、易读,选择最适合的方式来提升可维护性!🚀


希望这个讲解能帮你更好地理解 如何选择嵌套类、局部类、匿名类和 Lambda 表达式!🚀 🎯