string s = ""在字符串常量池中创建了真实对象,可安全调用方法;string s = null仅声明引用,未指向任何内存,调用方法会抛nullpointerexception。

String s = "" 和 String s = null 的内存行为差异
前者在字符串常量池中分配了一个真实对象,哪怕长度为 0,它仍是可调用方法的合法 String 实例;后者只是声明了一个引用变量,没指向任何堆内存或常量池位置,连对象头都没有。
典型现象:s.length() 在 s = "" 时返回 0,在 s = null 时直接抛 NullPointerException。
-
s == null是唯一安全判断“未初始化”的方式;s.equals("")必须确保s非null才能执行 -
""可参与字符串拼接(如"prefix" + s),null拼接会变成字面量"null"(JVM 自动调用String.valueOf(null)) -
String.isEmpty()内部等价于length() == 0,但只对非null对象有效
if 判断顺序错位导致 NPE 的真实案例
写成 if (s.equals("") || s.equals("reg")) 是危险的:只要 s 是 null,第一个 equals 就挂掉,后面根本不会执行。
正确姿势是把 null 检查放在最左边,利用短路逻辑:
if (s == null || s.isEmpty() || s.equals("reg"))
- 顺序不能颠倒——
||是从左到右求值,s == null为true时整个表达式立即结束 - 别用
s.length() == 0替代s.isEmpty(),两者语义一致,但后者更明确表达“空”意图 - 如果业务上
null和""含义不同(比如数据库字段:未填 vs 填了空值),就不能合并判断
数据库场景下 null 与 "" 的语义不可互换
ORM 映射时,null 通常对应 SQL 的 NULL,表示“未知/不适用”;"" 对应 '',表示“明确留空”。
例如用户注册表单:
- 头像 URL 字段为
null→ 用户还没上传,也不打算传 - 头像 URL 字段为
""→ 用户主动清空了头像,或提交时显式留空 - JDBC 获取列值时,
rs.getString("avatar")返回null表示 DB 中是NULL;返回""表示 DB 中存的是空字符串 - 别用
rs.getString("col") == null来判断是否为空字符串,那是两个独立状态
工具方法里最容易被忽略的边界点
很多人封装 StringUtils.isEmpty(String s),却忘了它只解决“是否为空或 null”,不解决“是否有效业务值”。
- 像
" "(含空格)这种,isEmpty()返回false,但业务上可能算“空” - 真正健壮的校验往往要组合:
s == null || s.trim().isEmpty() - 注意
trim()本身对null不安全,必须先判空再调用 - Apache Commons 的
StringUtils.isBlank()就是干这个的,但如果你不用第三方库,就得自己写清楚这层逻辑
null 是架子都没搭好,"" 是架子搭好了但里面啥也没放——处理逻辑得按这个物理事实来分层,而不是凭感觉合并判断。










