Java 最佳实践
Java 最佳实践
空值处理
判空前区分两种情况:null 是有效返回值(查询无结果)还是无效返回值(参数错误)。
策略一:null 无意义 → 抛异常
if (param == null) {
throw new IllegalArgumentException("参数不能为空");
}策略二:null 有意义 → 返回空替代值
返回空集合:
return Collections.emptyList(); // 调用方可直接遍历,无需判空空对象模式(Null Object Pattern)——返回"什么都不做"的对象替代 null:
parser.findAction(someInput).doSomething(); // 精简写法,无 NPE 风险equals 判空——常量在前:
"bar".equals(foo) // 正确
foo.equals("bar") // 可能 NPEOptional 容器(Java 8+):
Optional<String> name = Optional.ofNullable(getName());
name.ifPresent(n -> System.out.println(n));枚举比较
提示
核心结论 枚举比较用 ==,不用 equals——枚举保证单例,== 更快、更安全、编译期检测类型兼容性。
Color.BLACK == Chiral.LEFT; // 编译失败!类型不兼容(正确行为)
Color.BLACK.equals(Chiral.LEFT); // 编译通过(不应该)JLS 8.9:枚举类型除了定义的常量外没有其他实例,序列化、克隆、反射都无法创建新实例。
String 不可变性
| 原因 | 说明 |
|---|---|
| 字符串常量池 | 多变量共享同一对象 |
| 安全性 | 网络连接、文件路径等场景 |
| 线程安全 | 不可变对象天然线程安全 |
| 哈希码缓存 | hashCode 可缓存 |
"test" == "test" // true(常量池)
new String("test") == "test" // false
new String("test").equals("test") // trueBigDecimal
浮点数无法用二进制精确表示(2.0f - 1.9f = 0.100000024)。涉及金额计算必须用 BigDecimal。
创建方式
禁止 new BigDecimal(0.1),推荐 new BigDecimal("0.1") 或 BigDecimal.valueOf(0.1)。
a.add(b); // 加法
a.subtract(b); // 减法
a.multiply(b); // 乘法
a.divide(b, 2, RoundingMode.HALF_UP); // 除法(必须指定精度和舍入模式)泛型与 PECS 原则
| 符号 | 含义 | 角色 |
|---|---|---|
<? extends T> | 上界 | 生产者(只读) |
<? super T> | 下界 | 消费者(只写) |
PECS:Producer-Extends, Consumer-Super。
void read(List<? extends Number> list) { Number n = list.get(0); } // 读取
void write(List<? super Integer> list) { list.add(1); } // 写入序列化
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private transient int password; // 不序列化
}| 问题 | 解决 |
|---|---|
| 类结构变化 | 保持 serialVersionUID 一致 |
| 敏感字段 | 使用 transient |
| 单例序列化 | 添加 readResolve() |
日志规范
| 级别 | 用途 |
|---|---|
| ERROR | 影响功能的错误 |
| WARN | 不影响运行的警告 |
| INFO | 正常流程信息 |
| DEBUG | 开发调试 |
log.debug("用户登录: userId={}", userId); // 正确:占位符
log.debug("用户登录: " + userId); // 错误:字符串拼接异常处理
| 类型 | 说明 | 示例 |
|---|---|---|
| Checked Exception | 必须捕获 | IOException |
| Unchecked Exception | 可选捕获 | NullPointerException |
| Error | 不应捕获 | OutOfMemoryError |
注意
禁止吞异常 catch (Exception e) {} 会隐藏问题。必须至少记录日志。
自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}