讲解
走完二十五章,从变量到多线程都有了基础。最后一章不谈新语法,把散落在全书的经验收敛成一份可以直接照做的清单。命名与可读性排第一:类名大驼峰名词(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 后端、安卓、大数据),在真实项目里继续练级。