讲解

走完二十五章,从变量到多线程都有了基础。最后一章不谈新语法,把散落在全书的经验收敛成一份可以直接照做的清单。命名与可读性排第一:类名大驼峰名词(OrderService)、方法小驼峰动词(calculateTotal)、常量全大写(MAX_RETRY)、布尔变量用 is/has 开头(isValid);方法保持短小只做一件事,参数不超过三个为宜,超过就考虑封装成对象——代码被阅读的次数远多于被编写的次数,可读性就是生产力。

防御性习惯第二:字段一律 private,能 final 就 final(不可变对象天然线程安全、行为可预期);字符串等内容比较用 equals 或 Objects.equals,不用 ==;公开方法的开头校验参数,非法就快速抛 IllegalArgumentException;资源用 try-with-resources;集合声明面向接口(List list = new ArrayList<>());判断空值后再调用方法,Optional 可以表达「可能没有返回值」的语义,但字段和方法参数不要用它。

工程习惯第三:编译警告不要忽略,它们常常就是 bug 的前兆;异常要么妥善处理要么转换成有意义的业务异常抛出,绝不空 catch;写代码时同步写简单的方法级验证(哪怕先用 main 方法跑断言式的打印),能跑通的代码才算写完;版本控制(Git)从第一天就用,小步提交。学习路径方面:把本教程每个示例亲手敲一遍、改一改再跑,然后给自己立个小项目——命令行记账本、通讯录管理、单词背诵器都是绝佳的结业练习;遇到具体问题再回头查对应章节,用出来的知识才是自己的。

示例

一个贯彻良好习惯的完整小例子:final 字段、private 封装、参数校验、equals/hashCode、面向接口:

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

class Product {
    private final String name;
    private final double price;

    Product(String name, double price) {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("商品名不能为空");
        }
        if (price < 0) {
            throw new IllegalArgumentException("价格不能为负:" + price);
        }
        this.name = name;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public String toString() {
        return name + "(¥" + price + ")";
    }
}

class Cart {
    private final List<Product> items = new ArrayList<>();

    public void add(Product product) {
        Objects.requireNonNull(product, "商品不能为 null");
        items.add(product);
    }

    public double total() {
        return items.stream().mapToDouble(Product::getPrice).sum();
    }

    public void printReceipt() {
        items.forEach(item -> System.out.println(" - " + item));
        System.out.println(String.format("合计:¥%.2f", total()));
    }
}

public class Main {
    public static void main(String[] args) {
        Cart cart = new Cart();
        cart.add(new Product("机械键盘", 299.0));
        cart.add(new Product("无线鼠标", 99.0));
        cart.printReceipt();
    }
}

不良写法与推荐写法的对照速查(都能运行,体会差别):

import java.util.Objects;

public class Main {
    public static void main(String[] args) {
        String input = null;

        // 推荐:常量在前避免空指针
        System.out.println("是 admin 吗?" + "admin".equals(input));
        // 推荐:Objects.equals 天然空安全
        System.out.println("Objects.equals:" + Objects.equals(input, "admin"));

        // 推荐:拼接循环用 StringBuilder
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 3; i++) {
            sb.append("项").append(i).append(' ');
        }
        System.out.println(sb.toString().trim());

        // 推荐:提前返回代替深层嵌套
        System.out.println(describe(95));
        System.out.println(describe(-1));
    }

    static String describe(int score) {
        if (score < 0 || score > 100) {
            return "分数不合法";
        }
        if (score >= 60) {
            return "及格";
        }
        return "不及格";
    }
}

常见坑

  • 追逐「高级技巧」胜过清晰:一行流、炫技式链式调用让下一个人(包括未来的你)读不懂。清晰 > 简短 > 聪明。
  • 复制粘贴式编程:同一段逻辑出现第三次就该提炼成方法或类。重复代码意味着改一处漏三处的必然未来。
  • 不验证就当完成:编译通过 ≠ 逻辑正确。每个方法写完都用具体数据跑一遍边界:空值、0、最大值、重复值。
  • 攒大招不提交:写一整天才提交一次,出问题没法回退。小步快走:每个可运行的小改动就提交一次,提交信息写清「做了什么」。

小结

命名清晰、封装严实、快速失败、面向接口、小步验证——这些是陪你走很远的习惯。26 章到此结束:Java 的地基已经打好,接下来选一个方向深入(Web 后端、安卓、大数据),在真实项目里继续练级。