为何null类型Character与字符比较会抛NPE?是否等价于equals调用?
Character包装类与原生char比较的空指针坑点解析
嘿,这个问题问到点子上了,刚好戳中了Java里包装类自动拆箱的一个常见陷阱!咱们一步步拆解来聊:
一、为啥null的Character和char比较会炸NPE?
- 当你把包装类Character对象和原生char类型用
==比较时,Java会自动触发拆箱操作——就是把Character对象转换成对应的原生char值。 - 但如果Character对象是
null,拆箱的底层逻辑是调用charValue()方法,你想想,对一个null对象调用实例方法,这不直接抛出NullPointerException嘛!
二、你的代码示例为啥抛NPE?
先看这段代码:
Character c = null; if(c == ' ') { System.out.println("Is space"); }
这里的c == ' '就是触发了自动拆箱:JVM试图把null的c转成char,结果执行c.charValue()的时候,因为c是null,直接炸了NPE,这就是问题的核心。
三、这种写法是c.equals(' ')的语法糖吗?
完全不是!两者根本不是一回事,差异特别大:
- 执行逻辑天差地别:
c == ' '是先把Character拆箱成char,再做原生类型的值比较;c.equals(' ')是调用Character的equals方法,而equals的参数是Object,所以这里会先把原生char' '自动装箱成Character对象,再比较两个对象的底层char值。
- NPE触发时机不一样:
- 如果
c是null,c == ' '是在拆箱阶段抛NPE; - 而
c.equals(' ')是直接因为调用null对象的equals方法抛NPE,触发得更早。
- 如果
- 语义也不同:
==对拆箱后的原生类型是纯粹的数值比较;equals是对象相等性判断(虽然Character重写了equals,最终也是比较值,但前提是调用对象不为null)。
最后给个小建议:如果要安全比较,一定要先判空,比如:
Character c = null; if (c != null && c == ' ') { System.out.println("Is space"); }
或者用Java 8+的Optional来优雅处理null:
Optional.ofNullable(c) .filter(ch -> ch == ' ') .ifPresent(ch -> System.out.println("Is space"));
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

