Java中Character比较为何equals()失效但==可用?以有效括号题为例
有效括号问题中Character比较的坑
你的问题核心是:为什么原代码用==能正确运行,换成equals()就失效了?这是自动拆箱/装箱+对象类型匹配导致的问题,拆解如下:
原代码的逻辑为什么成立
原判断行:
if (check != (c - 1) && check != (c - 2))
这里的关键是自动拆箱机制:
c是Character类型,c - 1会触发自动拆箱,把Character转成对应的int类型(比如')'拆箱后是41,c-1就是40)。check也是Character类型,和int做!=比较时,同样会自动拆箱成int,本质是两个ASCII数值的比较,自然能正确判断括号的匹配关系(比如'('拆箱是40,和')'-1的40相等,所以check != 40为false,不会进入return false的逻辑)。
修改后代码失效的原因
修改后的判断行:
if (!check.equals(c - 1) && !check.equals(c - 2))
问题出在equals()的参数类型匹配上:
c - 1是int类型,调用Character.equals(int)时,Java会把int自动装箱成Integer对象。Character类的equals()方法会先检查参数类型:如果参数不是Character对象,直接返回false。- 比如输入
"()"时,check是Character('('),c-1是40(装箱成Integer(40)),check.equals(Integer(40))返回false,取反后是true;另一个条件!check.equals(c-2)同样为true,所以进入if块返回false,导致结果错误。
正确的修改方式
要让equals()生效,需要保证比较的是同类型对象,有两种可行方案:
方案1:把数值转成Character后再比较
if (!check.equals(Character.valueOf((char)(c - 1))) && !check.equals(Character.valueOf((char)(c - 2))))
先把c-1、c-2的int值转成char,再装箱为Character对象,这样和check类型一致,equals()就能正确比较值了。
方案2:先拆箱成基本类型再比较
显式拆箱避免对象类型问题,写法更清晰:
char checkChar = check; if (checkChar != (c - 1) && checkChar != (c - 2))
补充说明
原代码用==能运行,其实依赖了Java的Character缓存机制:对于ASCII码在-128到127之间的字符,Java会缓存对应的Character对象,所以==比较的是同一个对象的引用,结果等同于值比较。但如果是超出这个范围的字符,==就会失效。所以更严谨的写法还是优先用显式拆箱后的数值比较,或者正确装箱后的equals()比较。
内容的提问来源于stack exchange,提问作者BourneZ
相关产品推荐
相关产品推荐

