在 Java 中,null 关键字本身代表“无”或“空引用”,但两个 null 值的比较、方法调用、属性访问等操作,其结果和你直观的“等于”概念不完全一样。

下面我们从几个关键场景来深入理解。
使用 比较(最常见的情况)
这是最容易产生误解的地方。
比较的是两个引用变量是否指向内存中的同一个对象(同一个地址)。
-
当两个变量都被赋值为
null时: 它们都指向 JVM 中一个特殊的“空地址”,它们指向的是同一个“无”的概念,在这种情况下, 的判断结果是true。
(图片来源网络,侵删)String a = null; String b = null; System.out.println(a == b); // 输出 true
在这种情况下,
null等于null。 -
当一个变量为
null,另一个变量指向一个实际创建的对象时:null指向空地址,而另一个变量指向堆内存中某个对象的地址,地址不同, 的判断结果是false。String a = null; String b = new String("hello"); System.out.println(a == b); // 输出 false在这种情况下,
null不等于 一个非null的对象。
小结: 使用 比较两个 null 值,结果是 true。null 不等于 null”这个说法在 比较下是错误的。

使用 equals() 方法比较
equals() 方法通常用于比较对象的内容(值)是否相等,而不是内存地址。
-
当调用一个
null对象的equals()方法时: 这会直接导致NullPointerException(空指针异常),因为你试图通过一个“空引用”去访问一个方法。String a = null; String b = "hello"; // 错误的做法!会抛出异常 // System.out.println(a.equals(b)); // 正确的做法(推荐) System.out.println(Objects.equals(a, b)); // 输出 false
Objects.equals()方法内部做了安全的null检查,它的工作原理是:a是null,直接返回false(因为null不可能等于一个非null的对象)。a不是null,再调用a.equals(b)。
-
当两个变量都是
null时: 同样,直接调用a.equals(b)会抛出异常。 但使用Objects.equals(null, null),其结果是true,因为Objects类的equals方法认为两个null值是相等的。String a = null; String b = null; // 错误的做法!会抛出异常 // System.out.println(a.equals(b)); // 正确的做法 System.out.println(Objects.equals(a, b)); // 输出 true
小结:
- 直接对
null调用equals()会抛出异常,这是“null不等于null”这个说法的一个有力佐证(因为操作本身就不合法)。 - 使用工具类(如
Objects.equals())可以安全地比较,并且认为null等于null。
switch 语句中的 null
在 Java 7 及更高版本中,switch 语句可以接受 String 类型,但它不能接受 null。
-
switch的表达式计算结果为null,程序会抛出NullPointerException。String status = null; switch (status) { case "OPEN": System.out.println("状态是开启"); break; case "CLOSED": System.out.println("状态是关闭"); break; default: System.out.println("未知状态"); } // 这段代码会抛出 NullPointerException
在 switch 语句中,null 是一个非法的输入,它会中断程序,这体现了 null 的“不等于”特性,因为它不能被当作一个有效的 case 值来处理。
instanceof 操作符
instanceof 用于检查一个对象是否是某个特定类或其子类的实例。
-
当用
instanceof检查null时: 结果永远是false,因为null不代表任何类的实例。Object obj = null; System.out.println(obj instanceof String); // 输出 false System.out.println(null instanceof Object); // 输出 false
null 不 instance of 任何类型,这也是“null 不等于 null”思想的一种延伸——null 不是一个“东西”,所以它不属于任何类别。
| 操作 | 对 null 的行为 |
解释 | "null 不等于 null" 是否适用? |
|---|---|---|---|
a == b (当 a=null, b=null) |
true |
两个引用都指向同一个“空地址”。 | 不适用。null 等于 null。 |
a.equals(b) (当 a=null) |
NullPointerException |
尝试通过空引用访问方法,非法操作。 | 适用,操作本身无效,体现了“不等于”的特性。 |
Objects.equals(a, b) (当 a=null, b=null) |
true |
工具类方法,安全地将两个 null 视为相等。 |
不适用。null 等于 null。 |
switch (a) (当 a=null) |
NullPointerException |
switch 语句不接受 null 作为有效输入。 |
适用。null 不能被当作一个有效的 case 值。 |
a instanceof SomeClass (当 a=null) |
false |
null 不代表任何类的实例。 |
适用。null 不属于任何类型。 |
核心思想
“Java null 不等于 null” 这句话更像是一种编程哲学或警示,而不是一个严格的语法规则,它的真正含义是:
null 是一个特殊的、表示“无”的值,它不是一个普通的对象,你不能用对待普通对象的方式来对待它。
- 不要假设它有行为:不要对
null调用方法或访问属性,否则会得到NullPointerException。 - 不要假设它有类型:
instanceof会告诉你它不属于任何类型。 - 在比较时要多加小心:优先使用
Objects.equals()或String.equals(Object)这样的安全方式,而不是直接对null调用方法。
理解了 null 的这种“虚无”特性,就能写出更健壮、更不容易出错的 Java 代码。
