Java 的基础问题看起来简单,但很多线上 bug 都和对象边界有关:引用是不是同一个对象,equals 有没有重写,集合里对象能不能正确去重,序列化字段是否稳定。
理解这些基础,比背 API 更重要。
类是结构,对象是实例
类定义字段和行为,对象是运行时创建出来的实例。
class User {
private Long id;
private String name;
}
每次 new User() 都会创建一个新的对象。两个对象字段值一样,也不代表它们是同一个对象。
User a = new User();
User b = new User();
a == b 比较的是引用是否指向同一个对象,不是字段内容是否一样。
equals 和 hashCode 要一起看
如果对象需要放进 HashSet、作为 HashMap 的 key,或者需要按业务字段判断相等,就要认真处理 equals 和 hashCode。
只重写 equals 不重写 hashCode,集合行为可能异常。只看 id 还是看多个字段,也要按业务语义决定。
常见建议是:
- 实体对象按主键或唯一业务键判断。
- 值对象按所有关键字段判断。
- 可变字段尽量不要参与 hash key。
对象一旦放进 HashMap,再修改参与 hash 的字段,会导致后续查找失败。
包装类型要小心空值
Java 里 int 和 Integer 不一样。int 是基本类型,不能为 null;Integer 是对象,可以为 null。
接口入参、数据库字段和 JSON 反序列化时,经常使用包装类型。使用前要处理空值,否则自动拆箱可能触发 NullPointerException。
Integer count = null;
int value = count; // 可能 NPE
业务代码里,如果字段可以缺失,就不要假设它一定有值。
序列化字段要稳定
对象如果需要在网络、缓存、文件或消息队列中传输,就涉及序列化。
JSON 序列化最常见,但仍要注意:
- 字段名是否稳定。
- 日期格式是否明确。
- 空值是否输出。
- 枚举用 name 还是 code。
- 新增字段是否兼容旧消费者。
Java 原生序列化现在不太推荐作为通用方案。跨系统传输更常用 JSON、Protobuf、Avro 等明确协议。
实用结论
Java 基础不是语法题,而是对象边界题。==、equals、hashCode、包装类型空值和序列化字段,都会直接影响业务行为。
写对象模型时,先想清楚它是实体、值对象、传输对象还是持久化对象。角色清楚了,相等判断、字段可变性和序列化方式才不容易混乱。




