错误。map.merge()方法中若传入null作为value,会立即抛出nullpointerexception,因源码强制校验objects.requirenonnull(value),不会执行后续逻辑,更不会删除key。

Java 中 Map.merge 方法在传入 null 作为 value 时,**不会抛出异常,也不会保留原 key,而是直接删除该 key**——这是容易被忽略的隐蔽行为,尤其在业务逻辑依赖 key 存在性时可能引发空指针或数据丢失。
merge 的 null value 行为本质
merge(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction) 的语义是:
- 若 key 不存在,且
value != null,则 put(key, value); - 若 key 已存在,则用
remappingFunction合并旧值与新值(即remappingFunction.apply(oldValue, value)); -
若传入的
value == null,且 key 已存在,则默认执行remove(key)(前提是 remappingFunction 返回 null 或未被调用)。
注意:JDK 文档明确说明 —— “如果 value 为 null,且 key 已关联值,则该映射将被移除”,这个逻辑不依赖 remappingFunction 是否定义,只要 value 是 null 就触发删除。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
常见误用场景
以下写法看似无害,实则危险:
- 从外部读取配置/参数后直接 merge:
map.merge("status", user.getStatus(), (old, val) -> val);,若user.getStatus()返回 null,key 就被删了; - 条件赋值时忘记判空:
map.merge("count", condition ? 1 : null, Integer::sum);,null 会清掉 key; - 用 merge 替代 putIfAbsent,却未意识到 null 值的副作用。
安全替代方案
想避免意外删除,可按需选择:
- 显式判空再操作:先检查 value 是否为 null,再决定 put / remove / compute;
-
用 compute 系列方法替代:例如
map.compute(key, (k, v) -> value != null ? value : v),null 时保持原值不变; -
封装工具方法:如
safeMerge(map, key, value, remapper),内部拦截 null value 并跳过或抛出 IllegalArgumentException。
验证方式
快速确认行为是否符合预期:
- 写单元测试,覆盖
merge(k, null, ...)场景,断言 key 是否还存在; - 调试时留意 Map 实现类(如 HashMap、ConcurrentHashMap)对 merge 的具体实现,它们都遵循同一规范;
- 注意 IDE 提示或静态分析工具(如 SpotBugs)可能标记“null passed to merge”为潜在风险。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










