1
0

Java 入门指南:第二章 - 深入 Java 核心语法与面向对象进阶

2026-09-07
文章摘要
|

承接第一章的基础内容,本章将深入讲解 Java 核心语法细节、面向对象编程的进阶特性,以及一些实用的编程技巧。建议在阅读本章时,打开 IDE 同步编码实践。


第二章:Java 核心语法深度剖析

2.1 变量与数据类型的深入理解

2.1.1 变量的作用域与生命周期

变量根据声明位置和修饰符的不同,具有不同的作用域和生命周期:

public class VariableScope {
    // 成员变量(实例变量):属于对象,在堆内存中
    String instanceVar = "实例变量";
    
    // 静态变量(类变量):属于类,在方法区中
    static String staticVar = "静态变量";
    
    public void testMethod() {
        // 局部变量:在栈内存中,方法执行时创建,结束即销毁
        int localVar = 10;
        System.out.println(localVar);
        
        // 局部代码块中的变量:只在块内有效
        {
            String blockVar = "块变量";
            System.out.println(blockVar);
        }
        // System.out.println(blockVar); // 编译错误:找不到符号
    }
}

2.1.2 基本数据类型与引用数据类型的区别

对比维度 基本数据类型 引用数据类型
存储位置 栈内存(直接存储值) 堆内存(存储对象,栈存储引用地址)
默认值 有明确默认值(如 int 为 0) null
传递方式 值传递(传递副本) 值传递(传递引用地址副本)
比较操作 == 比较值 == 比较地址,equals() 比较内容
// 基本类型示例
int a = 10;
int b = a;  // b 是 a 的副本
b = 20;     // a 仍然是 10

// 引用类型示例
String str1 = new String("Hello");
String str2 = str1;  // str2 指向同一个对象
str2 = "World";      // str1 仍指向 "Hello"

// 数组引用传递
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr2[0] = 100;  // arr1[0] 也变成了 100

2.1.3 常量与 final 关键字

public class Constants {
    // 类常量(通常使用大写字母)
    public static final double PI = 3.14159;
    public static final String APP_NAME = "MyJavaApp";
    
    public void example() {
        // 局部常量
        final int MAX_SIZE = 100;
        // MAX_SIZE = 200; // 编译错误:不能重新赋值
        
        // final 修饰引用类型:不能改变指向,但可以修改对象内容
        final StringBuilder sb = new StringBuilder("Hello");
        sb.append(" World");  // 允许
        // sb = new StringBuilder("New"); // 编译错误
    }
}

2.2 运算符的进阶用法

2.2.1 位运算符(高效运算)

public class BitwiseOperators {
    public static void main(String[] args) {
        int a = 60;  // 二进制:0011 1100
        int b = 13;  // 二进制:0000 1101
        
        System.out.println("a & b = " + (a & b));   // 12  (0000 1100)
        System.out.println("a | b = " + (a | b));   // 61  (0011 1101)
        System.out.println("a ^ b = " + (a ^ b));   // 49  (0011 0001)
        System.out.println("~a = " + (~a));          // -61 (1100 0011)
        System.out.println("a << 2 = " + (a << 2));  // 240 (1111 0000)
        System.out.println("a >> 2 = " + (a >> 2));  // 15  (0000 1111)
        System.out.println("a >>> 2 = " + (a >>> 2));// 15  (无符号右移)
    }
}

2.2.2 运算符优先级(记忆口诀)

括号单目先,乘除取余后;
加减移位关系,逻辑三目赋值后。

详细优先级列表(从高到低):

  1. () [] .
  2. ++ -- ~ ! (单目)
  3. * / %
  4. + -
  5. << >> >>>
  6. < > <= >= instanceof
  7. == !=
  8. &
  9. ^
  10. |
  11. &&
  12. ||
  13. ? :
  14. = += -= *= /= %= &= ^= |= <<= >>= >>>=

2.3 流程控制的更多细节

2.3.1 多重选择:switch 的增强用法

Java 14+ 引入了更简洁的 switch 表达式:

public class SwitchAdvanced {
    public static void main(String[] args) {
        String day = "MONDAY";
        
        // 传统 switch 语句
        switch (day) {
            case "MONDAY":
            case "TUESDAY":
            case "WEDNESDAY":
            case "THURSDAY":
            case "FRIDAY":
                System.out.println("工作日");
                break;
            case "SATURDAY":
            case "SUNDAY":
                System.out.println("周末");
                break;
            default:
                System.out.println("无效日期");
        }
        
        // Java 14+ 的 switch 表达式(使用 ->)
        String result = switch (day) {
            case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "工作日";
            case "SATURDAY", "SUNDAY" -> "周末";
            default -> "无效日期";
        };
        System.out.println(result);
        
        // 使用 yield 返回值(适用于代码块)
        int numDays = switch (day) {
            case "MONDAY", "WEDNESDAY", "FRIDAY" -> {
                System.out.println("奇数日");
                yield 1;  // 返回值
            }
            case "TUESDAY", "THURSDAY" -> {
                System.out.println("偶数日");
                yield 2;
            }
            default -> 0;
        };
    }
}

2.3.2 循环控制的高级技巧

标签(Label)+ break/continue:跳出多重循环

public class LoopLabel {
    public static void main(String[] args) {
        // 使用标签跳出外层循环
        outerLoop:
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (i * j > 6) {
                    System.out.println("跳出外层循环:i=" + i + ", j=" + j);
                    break outerLoop;
                }
                System.out.print(i * j + " ");
            }
            System.out.println();
        }
        // 输出:0 0 0 0 0 
        //       0 1 2 3 4 
        //       0 2 4 6 
        //       跳出外层循环:i=2, j=3
    }
}

循环中避免陷阱

// 错误示例:浮点数比较导致死循环
for (double d = 0.0; d != 1.0; d += 0.1) {
    System.out.println(d);  // 永远不会等于 1.0(浮点数精度问题)
}

// 正确做法:使用整数或范围比较
for (int i = 0; i <= 10; i++) {
    double d = i / 10.0;
    System.out.println(d);
}

2.4 数组的高级操作

2.4.1 Arrays 工具类的使用

import java.util.Arrays;
import java.util.Comparator;

public class ArraysUtility {
    public static void main(String[] args) {
        int[] numbers = {5, 2, 8, 1, 9, 3};
        
        // 排序
        Arrays.sort(numbers);
        System.out.println(Arrays.toString(numbers)); // [1, 2, 3, 5, 8, 9]
        
        // 二分查找(必须先排序)
        int index = Arrays.binarySearch(numbers, 5);
        System.out.println("5 的位置:" + index); // 3
        
        // 填充数组
        int[] fillArr = new int[5];
        Arrays.fill(fillArr, 10);
        System.out.println(Arrays.toString(fillArr)); // [10, 10, 10, 10, 10]
        
        // 数组拷贝
        int[] copy = Arrays.copyOf(numbers, 10);
        System.out.println(Arrays.toString(copy)); // [1, 2, 3, 5, 8, 9, 0, 0, 0, 0]
        
        // 数组比较
        int[] arr1 = {1, 2, 3};
        int[] arr2 = {1, 2, 3};
        System.out.println(Arrays.equals(arr1, arr2)); // true
        
        // 对象数组排序(需要实现 Comparable)
        String[] names = {"张三", "李四", "王五", "赵六"};
        Arrays.sort(names, (a, b) -> b.compareTo(a)); // 降序
        System.out.println(Arrays.toString(names));
    }
}

2.4.2 可变参数(Varargs)

public class VarargsDemo {
    // 可变参数本质是数组
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    // 可变参数必须放在参数列表最后
    public static void printMessage(String prefix, int... values) {
        System.out.print(prefix + ": ");
        for (int v : values) {
            System.out.print(v + " ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        System.out.println(sum(1, 2, 3));      // 6
        System.out.println(sum(1, 2, 3, 4, 5)); // 15
        System.out.println(sum());              // 0
        
        printMessage("Values", 10, 20, 30);
    }
}

第三章:面向对象编程(OOP)进阶

3.1 构造方法深度解析

3.1.1 构造方法的重载与链式调用

public class Employee {
    private String name;
    private int age;
    private String department;
    
    // 无参构造器
    public Employee() {
        this("Unknown", 0, "Unassigned");
    }
    
    // 构造器重载
    public Employee(String name) {
        this(name, 0, "Unassigned");
    }
    
    // 主构造器
    public Employee(String name, int age, String department) {
        this.name = name;
        this.age = age;
        this.department = department;
        System.out.println("员工对象创建成功:" + this.name);
    }
    
    // 复制构造器(不是 Java 原生特性,但常用)
    public Employee(Employee other) {
        this(other.name, other.age, other.department);
    }
    
    // 使用
    public static void main(String[] args) {
        Employee e1 = new Employee();
        Employee e2 = new Employee("张三");
        Employee e3 = new Employee("李四", 25, "研发部");
        Employee e4 = new Employee(e3);  // 复制对象
    }
}

3.1.2 静态初始化块与实例初始化块

public class InitializationBlocks {
    // 静态变量
    private static int staticCounter;
    private String instanceData;
    
    // 静态初始化块(类加载时执行一次)
    static {
        staticCounter = 100;
        System.out.println("静态初始化块执行,staticCounter = " + staticCounter);
        // 不能访问非静态成员
    }
    
    // 实例初始化块(每次创建对象前执行)
    {
        instanceData = "Default";
        System.out.println("实例初始化块执行");
        // 可以访问静态成员
        staticCounter++;
    }
    
    // 构造方法
    public InitializationBlocks() {
        System.out.println("构造方法执行,instanceData = " + instanceData);
    }
    
    public InitializationBlocks(String data) {
        this.instanceData = data;
        System.out.println("构造方法执行,instanceData = " + instanceData);
    }
    
    public static void main(String[] args) {
        System.out.println("=== 创建第一个对象 ===");
        InitializationBlocks obj1 = new InitializationBlocks();
        
        System.out.println("\n=== 创建第二个对象 ===");
        InitializationBlocks obj2 = new InitializationBlocks("Custom Data");
        
        System.out.println("\n静态计数器:" + staticCounter); // 102
    }
}

3.2 继承的深入理解

3.2.1 super 关键字详解

class Parent {
    String name = "Parent";
    int age;
    
    public Parent() {
        System.out.println("Parent 无参构造器");
    }
    
    public Parent(int age) {
        this.age = age;
        System.out.println("Parent 带参构造器");
    }
    
    public void showInfo() {
        System.out.println("Parent 的 showInfo 方法");
    }
    
    public void display() {
        System.out.println("Parent 的 display 方法");
    }
}

class Child extends Parent {
    String name = "Child";
    
    public Child() {
        // super() 隐式调用(必须写在第一行)
        super(18);  // 显式调用父类带参构造器
        System.out.println("Child 构造器执行");
    }
    
    public void showInfo() {
        // 使用 super 访问父类成员
        System.out.println("父类的 name = " + super.name);
        System.out.println("当前类的 name = " + this.name);
        super.showInfo();  // 调用父类方法
        System.out.println("Child 的 showInfo 方法扩展");
    }
    
    @Override
    public void display() {
        System.out.println("Child 重写了 display 方法");
        // super.display(); // 可选调用
    }
    
    public static void main(String[] args) {
        Child child = new Child();
        child.showInfo();
        child.display();
        
        // 多态的体现
        Parent p = new Child();
        p.showInfo();  // 调用 Child 的重写方法
        // p.uniqueMethod(); // 编译错误:父类引用无法调用子类特有方法
    }
}

3.2.2 继承中的构造方法调用顺序

class GrandParent {
    public GrandParent() {
        System.out.println("1. GrandParent 构造器");
    }
}

class Parent2 extends GrandParent {
    public Parent2() {
        System.out.println("2. Parent2 构造器");
    }
    
    public Parent2(String msg) {
        System.out.println("3. Parent2 带参构造器:" + msg);
    }
}

class Child2 extends Parent2 {
    public Child2() {
        // 隐式 super()
        System.out.println("4. Child2 构造器");
    }
    
    public Child2(String msg) {
        super(msg);  // 显式调用
        System.out.println("5. Child2 带参构造器:" + msg);
    }
    
    public static void main(String[] args) {
        System.out.println("=== 创建 Child2 无参对象 ===");
        Child2 c1 = new Child2();  // 输出顺序:1→2→4
        
        System.out.println("\n=== 创建 Child2 带参对象 ===");
        Child2 c2 = new Child2("Test");  // 输出顺序:1→3→5
    }
}

3.3 多态的深度应用

3.3.1 向上转型与向下转型

interface Animal {
    void makeSound();
}

class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪汪!");
    }
    
    public void wagTail() {
        System.out.println("狗摇尾巴");
    }
}

class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵喵!");
    }
    
    public void scratch() {
        System.out.println("猫抓沙发");
    }
}

public class PolymorphismDemo {
    public static void main(String[] args) {
        // 向上转型(自动):子类→父类
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        // 调用重写的方法
        animal1.makeSound();  // 汪汪汪!
        animal2.makeSound();  // 喵喵喵!
        
        // 向下转型(需要强制):父类→子类
        // 需要先用 instanceof 检查
        if (animal1 instanceof Dog) {
            Dog dog = (Dog) animal1;
            dog.wagTail();  // 狗摇尾巴
        }
        
        if (animal2 instanceof Cat) {
            Cat cat = (Cat) animal2;
            cat.scratch();  // 猫抓沙发
        }
        
        // ClassCastException 示例(转型失败)
        // Dog invalidDog = (Dog) animal2; // 运行时错误:ClassCastException
    }
}

3.3.2 多态的应用:工厂模式示例

// 抽象产品
interface Shape {
    void draw();
    double getArea();
}

// 具体产品
class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制圆形,半径:" + radius);
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    private double width, height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制矩形,宽:" + width + ",高:" + height);
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
}

// 工厂类
class ShapeFactory {
    public static Shape createShape(String type, Object... params) {
        switch (type.toUpperCase()) {
            case "CIRCLE":
                return new Circle((double) params[0]);
            case "RECTANGLE":
                return new Rectangle((double) params[0], (double) params[1]);
            default:
                throw new IllegalArgumentException("不支持的图形类型:" + type);
        }
    }
}

public class FactoryPatternDemo {
    public static void main(String[] args) {
        Shape shape1 = ShapeFactory.createShape("circle", 5.0);
        Shape shape2 = ShapeFactory.createShape("rectangle", 4.0, 6.0);
        
        // 使用多态统一处理
        Shape[] shapes = {shape1, shape2};
        for (Shape shape : shapes) {
            shape.draw();
            System.out.println("面积:" + shape.getArea());
            System.out.println("---");
        }
    }
}

3.4 抽象类与接口的深度对比

3.4.1 抽象类的高级用法

abstract class AbstractDatabase {
    // 抽象方法:必须由子类实现
    public abstract void connect();
    
    public abstract void disconnect();
    
    // 具体方法:可被子类继承或重写
    public void executeQuery(String sql) {
        System.out.println("执行查询:" + sql);
        // 可以包含通用逻辑
    }
    
    // 模板方法模式
    public final void executeTransaction(Runnable transaction) {
        connect();
        try {
            transaction.run();
            System.out.println("事务提交成功");
        } catch (Exception e) {
            System.out.println("事务回滚:" + e.getMessage());
        } finally {
            disconnect();
        }
    }
}

class MySQLDatabase extends AbstractDatabase {
    @Override
    public void connect() {
        System.out.println("连接到 MySQL 数据库");
    }
    
    @Override
    public void disconnect() {
        System.out.println("断开 MySQL 连接");
    }
    
    // 可选:重写父类方法
    @Override
    public void executeQuery(String sql) {
        System.out.println("MySQL 执行:" + sql);
    }
}

public class AbstractClassDemo {
    public static void main(String[] args) {
        MySQLDatabase db = new MySQLDatabase();
        db.executeTransaction(() -> {
            System.out.println("执行数据库操作...");
        });
    }
}

3.4.2 接口的新特性(Java 8+)

// Java 8 开始,接口可以包含 default 和 static 方法
interface ModernInterface {
    // 抽象方法(仍然是必须实现的)
    void abstractMethod();
    
    // 默认方法(可以有实现,子类可重写也可不重写)
    default void defaultMethod() {
        System.out.println("接口的默认方法");
        privateMethod();  // 可以调用私有方法
    }
    
    // 静态方法(属于接口本身)
    static void staticMethod() {
        System.out.println("接口的静态方法");
        // 静态方法中不能调用默认方法
    }
    
    // Java 9 引入私有方法(在接口中复用代码)
    private void privateMethod() {
        System.out.println("接口的私有方法");
    }
}

class InterfaceImpl implements ModernInterface {
    @Override
    public void abstractMethod() {
        System.out.println("实现抽象方法");
    }
    
    // 可选:重写默认方法
    @Override
    public void defaultMethod() {
        System.out.println("重写默认方法");
        // 使用 super 调用父接口的默认方法
        ModernInterface.super.defaultMethod();
    }
}

public class InterfaceFeatures {
    public static void main(String[] args) {
        InterfaceImpl impl = new InterfaceImpl();
        impl.abstractMethod();
        impl.defaultMethod();
        
        // 调用接口静态方法
        ModernInterface.staticMethod();
    }
}

3.4.3 抽象类 vs 接口(选择指南)

特性 抽象类 接口(Java 8+)
关键字 abstract class interface
继承/实现 单继承 多实现
实例变量 可以 必须是 public static final
构造方法 可以有 不能有
访问修饰符 任意 public(default/static 方法可为 private)
使用场景 "是什么"(is-a) "能做什么"(can-do)
// 实际开发中的典型使用
interface Readable {
    void read();
}

interface Writable {
    void write();
}

abstract class FileHandler implements Readable, Writable {
    protected String filePath;
    
    public FileHandler(String filePath) {
        this.filePath = filePath;
    }
    
    // 可以只实现部分接口方法
    @Override
    public void read() {
        System.out.println("读取文件:" + filePath);
    }
    
    // 保留 write 为抽象
    public abstract void write();
}

class TextFileHandler extends FileHandler {
    public TextFileHandler(String path) {
        super(path);
    }
    
    @Override
    public void write() {
        System.out.println("写入文本文件:" + filePath);
    }
}

3.5 内部类(Nested Classes)

3.5.1 四种内部类

public class OuterClass {
    private static String staticField = "静态字段";
    private String instanceField = "实例字段";
    
    // 1. 静态内部类
    public static class StaticNested {
        public void display() {
            System.out.println("静态内部类访问:" + staticField);
            // 不能访问实例字段
            // System.out.println(instanceField); // 编译错误
        }
    }
    
    // 2. 实例内部类
    public class Inner {
        public void display() {
            System.out.println("实例内部类访问:" + instanceField);
            System.out.println("实例内部类访问:" + staticField);
            // 可以访问外部类的方法
            outerMethod();
        }
    }
    
    // 3. 局部内部类(在方法中)
    public void methodWithLocalInner() {
        final String localVar = "局部变量";  // Java 8 后可省略 final
        
        class LocalInner {
            public void print() {
                System.out.println("局部内部类:" + localVar);
                System.out.println("访问外部字段:" + instanceField);
            }
        }
        
        LocalInner inner = new LocalInner();
        inner.print();
    }
    
    // 4. 匿名内部类(最常用)
    public void createAnonymous() {
        // 实现接口的匿名内部类
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类实现 Runnable");
            }
        };
        runnable.run();
        
        // 继承类的匿名内部类
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("匿名内部类继承 Thread");
            }
        };
        thread.start();
    }
    
    private void outerMethod() {
        System.out.println("外部类方法");
    }
    
    public static void main(String[] args) {
        // 使用静态内部类
        StaticNested staticNested = new StaticNested();
        staticNested.display();
        
        // 使用实例内部类(需要外部类实例)
        OuterClass outer = new OuterClass();
        Inner inner = outer.new Inner();
        inner.display();
        
        outer.methodWithLocalInner();
        outer.createAnonymous();
    }
}

3.5.2 Lambda 表达式(函数式编程)

import java.util.*;
import java.util.function.*;

public class LambdaDemo {
    public static void main(String[] args) {
        // 传统方式:匿名内部类
        Comparator<Integer> comp1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer a, Integer b) {
                return a - b;
            }
        };
        
        // Lambda 表达式(简化)
        Comparator<Integer> comp2 = (a, b) -> a - b;
        
        // 更简洁的写法(方法引用)
        Comparator<Integer> comp3 = Integer::compare;
        
        // 常见使用场景
        List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9, 3);
        
        // 排序
        numbers.sort((a, b) -> b - a);  // 降序
        System.out.println(numbers);
        
        // 遍历
        numbers.forEach(n -> System.out.print(n + " "));
        System.out.println();
        
        // 过滤
        numbers.stream()
               .filter(n -> n > 5)
               .map(n -> n * n)
               .forEach(n -> System.out.print(n + " "));
        // 输出:64 81
    }
}

第四章:实用工具与最佳实践

4.1 枚举(Enum)

public enum Status {
    // 枚举常量(相当于调用构造器)
    PENDING("待处理", 0),
    PROCESSING("处理中", 1),
    SUCCESS("成功", 2),
    FAILED("失败", 3);
    
    // 字段
    private final String description;
    private final int code;
    
    // 构造器(必须是 private)
    Status(String description, int code) {
        this.description = description;
        this.code = code;
    }
    
    // Getter 方法
    public String getDescription() {
        return description;
    }
    
    public int getCode() {
        return code;
    }
    
    // 方法
    public boolean isFinished() {
        return this == SUCCESS || this == FAILED;
    }
    
    // 静态方法
    public static Status fromCode(int code) {
        for (Status status : Status.values()) {
            if (status.code == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("无效的 code:" + code);
    }
}

// 使用示例
class EnumExample {
    public static void main(String[] args) {
        Status current = Status.PROCESSING;
        
        System.out.println("状态:" + current);
        System.out.println("描述:" + current.getDescription());
        System.out.println("是否完成:" + current.isFinished());
        
        // 遍历
        for (Status s : Status.values()) {
            System.out.println(s + " - " + s.getDescription());
        }
        
        // switch 中使用
        switch (current) {
            case PENDING:
                System.out.println("等待处理");
                break;
            case PROCESSING:
                System.out.println("正在处理");
                break;
            case SUCCESS:
                System.out.println("处理成功");
                break;
            case FAILED:
                System.out.println("处理失败");
                break;
        }
        
        // 从 code 获取枚举
        Status status = Status.fromCode(2);
        System.out.println("Code 2 对应:" + status);
    }
}

4.2 常用设计模式示例

4.2.1 单例模式(线程安全)

// 饿汉式(推荐,简单线程安全)
public class SingletonEager {
    private static final SingletonEager INSTANCE = new SingletonEager();
    
    private SingletonEager() {}
    
    public static SingletonEager getInstance() {
        return INSTANCE;
    }
}

// 懒汉式(双重检查锁定)
public class SingletonLazy {
    private static volatile SingletonLazy instance;
    
    private SingletonLazy() {}
    
    public static SingletonLazy getInstance() {
        if (instance == null) {
            synchronized (SingletonLazy.class) {
                if (instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}

// 静态内部类(推荐)
public class SingletonHolder {
    private SingletonHolder() {}
    
    private static class Holder {
        private static final SingletonHolder INSTANCE = new SingletonHolder();
    }
    
    public static SingletonHolder getInstance() {
        return Holder.INSTANCE;
    }
}

4.2.2 构建者模式(Builder Pattern)

public class User {
    // 必需字段
    private final String username;
    private final String email;
    
    // 可选字段
    private final String phone;
    private final int age;
    private final String address;
    
    // 私有构造器
    private User(Builder builder) {
        this.username = builder.username;
        this.email = builder.email;
        this.phone = builder.phone;
        this.age = builder.age;
        this.address = builder.address;
    }
    
    // 静态内部 Builder 类
    public static class Builder {
        // 必需字段
        private final String username;
        private final String email;
        
        // 可选字段(初始化默认值)
        private String phone = "";
        private int age = 0;
        private String address = "";
        
        public Builder(String username, String email) {
            this.username = username;
            this.email = email;
        }
        
        public Builder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public Builder age(int age) {
            this.age = age;
            return this;
        }
        
        public Builder address(String address) {
            this.address = address;
            return this;
        }
        
        public User build() {
            return new User(this);
        }
    }
    
    // Getter 方法
    public String getUsername() { return username; }
    public String getEmail() { return email; }
    public String getPhone() { return phone; }
    public int getAge() { return age; }
    public String getAddress() { return address; }
    
    @Override
    public String toString() {
        return "User{username='" + username + "', email='" + email + 
               "', phone='" + phone + "', age=" + age + 
               ", address='" + address + "'}";
    }
    
    // 使用示例
    public static void main(String[] args) {
        User user = new User.Builder("张三", "zhangsan@example.com")
                .phone("13800138000")
                .age(25)
                .address("北京市海淀区")
                .build();
        
        System.out.println(user);
    }
}

4.3 异常处理最佳实践

public class ExceptionBestPractice {
    // 1. 使用具体的异常类型,而不是 Exception
    // 2. 捕获异常时进行有意义的处理
    // 3. 使用 try-with-resources 自动释放资源
    
    public void readFile(String filePath) {
        // try-with-resources(自动关闭资源)
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            // 记录日志并转换为业务异常
            System.err.println("文件未找到: " + filePath);
            throw new RuntimeException("文件不存在", e);
        } catch (IOException e) {
            System.err.println("读取文件失败: " + e.getMessage());
            throw new RuntimeException("文件读取错误", e);
        }
    }
    
    // 4. 自定义异常
    public void validateAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("年龄必须在 0-150 之间,实际值:" + age);
        }
    }
    
    // 5. 异常链
    public void processData() {
        try {
            riskyOperation();
        } catch (SQLException e) {
            // 包装异常并添加业务上下文
            throw new RuntimeException("数据处理失败", e);
        }
    }
    
    private void riskyOperation() throws SQLException {
        // 模拟风险操作
        throw new SQLException("数据库连接失败");
    }
}

第五章:下一步学习建议

完成本章内容后,你已经掌握了 Java 的核心语法和面向对象编程的精髓。接下来可以:

5.1 学习路线延伸

  1. 集合框架:深入研究 ArrayList、LinkedList、HashMap、HashSet 等
  2. IO 与 NIO:文件操作、流处理
  3. 多线程:线程创建、同步、锁、并发工具
  4. 网络编程:Socket、HTTP 客户端
  5. JDBC:数据库连接和操作
  6. Java Web:Servlet、JSP、Spring Boot

5.2 推荐实践项目

  • 控制台版学生管理系统(巩固面向对象)
  • 简单的聊天室(多线程 + 网络)
  • 图书管理系统(集合 + JDBC)
  • 个人博客系统(Spring Boot + Thymeleaf)

5.3 学习资源推荐

  • 书籍:《Effective Java》(Java 编程圣经)
  • 网站:Baeldung、Stack Overflow、GitHub
  • 社区:Java 技术栈、掘金、CSDN

结语

Java 是一门博大精深的语言,本章内容为你打下了坚实的基础。记住:

理解概念 → 动手编码 → 深入源码 → 项目实践

这是学习 Java 最有效的循环路径。遇到问题时,不要畏惧,每一次调试都是提升的机会。现在,打开你的 IDE,将本章的代码都实践一遍吧!

下一章预告:我们将深入 Java 集合框架,带你掌握最常用的数据结构和算法实现。敬请期待!🎯

评论