72. Java 嵌套类 - 局部类

72 阅读4分钟

72. Java 嵌套类 - 局部类

局部类(Local Classes)介绍

局部类是定义在某个代码块(例如方法、构造器或代码块)内部的类,其作用范围仅限于声明它的代码块内。你可以简单地把局部类理解为“方法内部的私有小工具”,它通常用于封装一些辅助逻辑,使得代码更加清晰,而这些逻辑不需要在整个类中使用。


1. 局部类与成员内部类的区别
  • 成员内部类(Inner Class) 是外部类的一个成员,可以在整个外部类中访问,生命周期与外部类实例绑定。
  • 局部类(Local Class) 定义在方法或代码块内部,仅在该作用域内可见和使用。适用于封装仅在局部使用的逻辑。

2. 局部类示例:验证电话号码格式

需求描述:

  • 我们有两个电话号码 phoneNumber1phoneNumber2,需要验证它们是否为有效的 10 位北美号码。
  • 规则:先去除所有非数字字符(如 -、空格),然后判断剩余字符的长度是否为 10
  • 如果符合要求,则认为电话号码合法,否则视为无效。

代码示例解析:

  • 正则表达式 regularExpression = "[^0-9]" 用于匹配所有非数字字符。利用 replaceAll 方法,将电话号码中的 -、空格等字符去除,只保留数字。
  • 局部类 PhoneNumber 定义在 validatePhoneNumber 方法内部,作用范围仅限于该方法。该类有一个构造方法用于格式化电话号码:
    • 将输入号码中的非数字字符去除。
    • 检查去除后的号码长度是否为 10 ,如果是,则认为该号码合法,存入 formattedPhoneNumber;否则置为 null
  • 方法 validatePhoneNumber 在该方法中创建了两个 PhoneNumber 对象,分别处理两个电话号码,并输出验证结果。

代码实现:

public class LocalClassExample {

    static String regularExpression = "[^0-9]"; // 匹配非数字字符的正则表达式

    public static void validatePhoneNumber(String phoneNumber1, String phoneNumber2) {
        final int numberLength = 10; // 规定电话号码长度

        // 在方法内部定义局部类
        class PhoneNumber {
            String formattedPhoneNumber = null;

            // 构造方法:格式化电话号码
            PhoneNumber(String phoneNumber) {
                // 去掉所有非数字字符
                String currentNumber = phoneNumber.replaceAll(regularExpression, "");
                // 判断长度是否为 10
                if (currentNumber.length() == numberLength) {
                    formattedPhoneNumber = currentNumber;
                } else {
                    formattedPhoneNumber = null;
                }
            }

            public String getNumber() {
                return formattedPhoneNumber;
            }
        }

        // 创建局部类的实例
        PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1);
        PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2);

        // 输出验证结果
        if (myNumber1.getNumber() == null) {
            System.out.println("First number is invalid");
        } else {
            System.out.println("First number is " + myNumber1.getNumber());
        }

        if (myNumber2.getNumber() == null) {
            System.out.println("Second number is invalid");
        } else {
            System.out.println("Second number is " + myNumber2.getNumber());
        }
    }

    public static void main(String... args) {
        validatePhoneNumber("123-456-7890", "456-7890");
    }
}

运行结果:

First number is 1234567890
Second number is invalid

解释:

  • 第一个号码 "123-456-7890" 去除非数字字符后变成 "1234567890",正好 10 位,因此合法。
  • 第二个号码 "456-7890" 处理后只有 7 位数字,不符合 10 位要求,因此视为无效。

3. 局部类的特性
  • 作用域限制 局部类只能在定义它的方法或代码块内使用,方法外无法访问。
  • 对外部变量的访问 局部类可以访问方法中的局部变量,但这些变量必须是 final 或“effectively final”(即变量在方法执行过程中不发生改变)。
  • 功能完整 局部类可以像普通类一样定义构造方法、成员变量和方法,但不能声明 static 成员,因为局部类属于方法级别。

4. 局部类的应用场景
  • 数据格式转换 如电话号码、日期格式转换等。
  • 方法内部的小工具类 用于封装一些仅在方法内部使用的辅助逻辑。
  • 数据过滤与处理 例如对集合中的数据进行筛选或转换。

但如果需要的类在多个方法中共享或逻辑复杂,则更适合使用成员内部类或独立类。


5. 总结
  • 局部类 = 方法内部的私有小工具 只在方法或代码块内部使用,作用范围局限于局部环境。
  • 优点:
    • 将逻辑封装在局部作用域内,使代码更加模块化和清晰。
    • 不会污染外部类的命名空间。
  • 限制:
    • 不能定义 static 成员。
    • 只能访问方法中的 final 或 effectively final 变量。
    • 作用范围仅限于定义它的代码块。

通过这个示例,你可以清晰地看到局部类如何帮助我们在方法内部处理复杂逻辑,同时避免将这些逻辑暴露到全局范围。