equals/hashCode · String常量池 · 异常体系 · 泛型擦除 · 自动装箱 · 面试高频坑
| # | 契约 | 含义 | 违反后果 |
|---|---|---|---|
| 1 | 自反性 | x.equals(x) == true | 放入集合后找不到 |
| 2 | 对称性 | x.equals(y) ↔ y.equals(x) | 两个集合包含关系不一致 |
| 3 | 传递性 | x=y, y=z → x=z | 链式比较出错 |
| 4 | 一致性 | 多次调用结果不变 | 集合行为不确定 |
| 5 | hashCode一致性 | equals为true → hashCode必须相同 | HashMap/HashSet失效 |
@Transactional 默认只回滚 RuntimeException和Error,不回滚Checked Exception!@Transactional(rollbackFor = Exception.class) → 所有异常都回滚
List<String> 和 List<Integer> 在运行时是同一个类(List)!new T()、不能 instanceof List<String>、不能创建泛型数组
float f = 3.4; → 编译错误:incompatible typesfloat f = 3.4f;float f = (float)3.4;switch(status) { ... } → status为null时炸if (status == null) return; switch(status) { ... }
List<String> sub = list.subList(0, 3);List<String> copy = new ArrayList<>(list.subList(0, 3));
0.1 + 0.2 = 0.30000000000000004 ≠ 0.3new BigDecimal("0.1").add(new BigDecimal("0.2")) → 0.3 精确new BigDecimal(0.1) 也不精确!必须用字符串构造:new BigDecimal("0.1")
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));int test() { try { return 1; } finally { return 2; } } → 返回2!int test() { int i = 1; try { return i; } finally { i = 2; } } → 返回1!(return时已经缓存了值)s = s + 1; → 编译错误:incompatible typess = (short)(s + 1);s += 1; → 编译器自动帮你强转(复合赋值运算符的隐藏特性)atomicI.incrementAndGet();synchronized(lock) { i++; }adder.increment();
| 陷阱 | 错误写法 | 正确做法 |
|---|---|---|
| equals/hashCode | 只重写equals | 必须一起重写 |
| String == | 用==比较字符串 | 用equals() |
| Integer == | 用==比较Integer | 用equals() |
| 自动拆箱NPE | Integer num=null; int i=num; | 先判空再拆箱 |
| Checked异常 | @Transactional不配rollbackFor | rollbackFor=Exception.class |
| 泛型擦除 | 运行时检查泛型类型 | 用Class<T>传参 |
| float字面量 | float f = 3.4; | float f = 3.4f; |
| 金额计算 | double计算金额 | BigDecimal或整数分 |
| Arrays.asList | 直接add/remove | new ArrayList<>(Arrays.asList(...)) |
| subList | 修改原List后操作subList | 创建副本new ArrayList(subList) |
— 全栈资料库 · Java基础陷阱图解 —
Java基础陷阱三原则:① equals/hashCode 必须同时重写,HashSet/HashMap 才能正常工作 → ② String 不可变 + 常量池,intern() 慎用 → ③ 受检异常用于可恢复、非受检异常用于编程错误