本文目录导读:

针对Java类结构的精简,核心原则是:减少冗余、明确职责、利用语言特性(如记录类)。
以下是几种常见的精简案例,从不同角度展示了如何让代码更简洁、更易维护。
核心场景:数据载体(POJO/DTO)的精简
这是最常见的精简案例,传统写法包含大量样板代码。
传统冗长写法:
public class User {
private String name;
private int age;
private String email;
// 无参构造函数
public User() {}
// 全参构造函数
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Getter 和 Setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
// equals, hashCode, toString 也需要手动或 IDE 生成
}
精简方案 1:使用 record(Java 16+ 推荐)
这是最彻底的简化。record 自动生成构造函数、equals()、hashCode()、toString() 以及 getter(形式为 name(), age() 而非 getName())。
public record User(String name, int age, String email) {}
优势: 简洁、不可变、线程安全、语义清晰(表明它只是一个数据值)。
精简方案 2:使用 Lombok(Java 8+ 兼容)
如果无法使用 record,Lombok 的 @Data 注解是最佳选择。
import lombok.Data;
@Data
public class User {
private String name;
private int age;
private String email;
}
优势: 兼容旧版本,仍然保留了设置器,灵活性强。
核心场景:工具类的精简
工具类通常不应被实例化,传统做法需要私有构造器。
传统冗长写法:
public class StringUtils {
// 私有构造器,防止实例化
private StringUtils() {
throw new AssertionError("Utility class should not be instantiated!");
}
// 静态方法
public static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
}
精简方案:使用 interface 的 private 方法或 static 方法
更现代的方式是利用 Java 8 的 interface 特性。
public interface StringUtils {
// interface 的 static 方法,无需实例化
static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
}
优势: 无需构造函数,语义更清晰(这是一个功能集合),并且无法被实例化。
核心场景:策略模式与函数式编程的精简
当类只有一个方法(如实现一个策略或行为接口),使用匿名内部类会显得臃肿。
传统冗长写法:
// 需要额外定义实现类
class AddOperation implements Operation {
@Override
public int apply(int a, int b) { return a + b; }
}
public class Calculator {
public int calculate(int a, int b, Operation op) {
return op.apply(a, b);
}
public static void main(String[] args) {
Calculator calc = new Calculator();
// 使用匿名内部类
int result = calc.calculate(5, 3, new Operation() {
@Override
public int apply(int a, int b) {
return a * b;
}
});
}
}
interface Operation {
int apply(int a, int b);
}
精简方案:使用 Lambda 表达式和 FunctionalInterface
如果接口只有一个抽象方法,它就是函数式接口,可以直接用 lambda。
// 直接使用 lambda
public class Calculator {
public int calculate(int a, int b, IntBinaryOperator op) { // 改用JDK自带的Function
return op.applyAsInt(a, b);
}
public static void main(String[] args) {
Calculator calc = new Calculator();
// 精简为一行
int result = calc.calculate(5, 3, (a, b) -> a * b);
int result2 = calc.calculate(5, 3, Integer::sum); // 方法引用,更简洁
}
}
优势: 无需定义新类,代码行数从20+行缩减到1行,代码量减少90%以上。
核心场景:单例模式的精简
传统双重检查锁定写法:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
精简方案:使用 enum
这是《Effective Java》作者强烈推荐的方式。
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
优势: 绝对防止多次实例化(即使反射也无法破坏),线程安全,代码极致简洁。
精简的通用原则
| 场景 | 精简手段 | 关键代码量对比 |
|---|---|---|
| 数据类 | record / Lombok @Data |
5-10行 → 1行 |
| 无状态工具类 | interface + static 方法 |
10+行 → 2行 |
| 策略/行为类 | Lambda + FunctionalInterface |
定义类 + 匿名内部类 → 1行 |
| 单例 | enum |
20+行 → 1行 |
| 需要返回常量集合 | List.of() / Set.of() (Java 9+) |
new ArrayList + add等 → 1行 |
思维转变建议: 下次写一个类时,先问自己三个问题:
- 这个类是描述数据还是描述行为?
- 数据 --> 用
record或Lombok。
- 数据 --> 用
- 这个类只有一个方法吗?
- 是 --> 试试写成
lambda或用static方法代替。
- 是 --> 试试写成
- 这个类的实例化是必需的吗?
- 不是 --> 用
interface的static方法或enum。
- 不是 --> 用