Groovy:比较 `"8" > 16` 有效,而 `"16" > 16` 抛出 ClassCastException 异常

Groovy: comparing `"8" > 16` works and `"16" > 16` throws ClassCastException exception

我在 Groovy shell 中执行以下表达式:

groovy:000> '8' > 16

===> true

但是当执行如下表达式时:

groovy:000> '16' > 16

它抛出以下异常:

ERROR java.lang.ClassCastException:

java.lang.Integer cannot be cast to java.lang.String

'8' > 16的情况下,我认为它是'8' > '16',所以它比较两个字符串的字典顺序。为什么它不能将 16 转换为 '16'?这个异常是什么意思?

我的 groovy 版本是:

Groovy Version: 2.4.8 JVM: 1.7.0_80 Vendor: Oracle Corporation OS: Linux

Groovy 通过 DefaultGroovyMethods a custom compareTo() 方法添加到 CharacterNumber 类,允许您将字符的 ASCII 序号与数字值进行比较。这意味着当你执行:

'z' > 12

在GroovyShell中,编译器调用:

org.codehaus.groovy.runtime.DefaultGroovyMethods.compareTo((char) 'z', 12)

方法代替,因为单个字符 String 等同于 Character。执行时会发生类似的事情:

12 > 'z'

编译器将其视为:

org.codehaus.groovy.runtime.DefaultGroovyMethods.compareTo(12, (char) 'z')

然而,当你执行如下表达式时:

'16' > 16

执行以下方法:

'16'.compareTo(16) // String.compareTo(String other) <-- passing Integer value throws ClassCastException

这是因为大小为 2(或更大)的 String 不等同于 Character。这就是为什么你得到:

ERROR java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String

因为没有方法 String.compareTo(Number n) 并且在这种情况下编译器不会将 Number 直接转换为 String。它尝试执行 String.compareTo(String other) 方法并传递一个与 String 类型不同的参数,在这种情况下会抛出 ClassCastException

如果您直接将 16 转换为 String,编译器将不再报错:

'16' > (String) 16

希望对您有所帮助。