Reputation: 164
I execute following expression in Groovy shell:
groovy:000> '8' > 16
===> true
But when execute expression like:
groovy:000> '16' > 16
it throws following exception:
ERROR java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String
In case of '8' > 16
, I think it is '8' > '16'
, so it compares dictionary order of two strings. Why it cannot convert 16
to '16'
? What does this exception mean?
My groovy version is:
Groovy Version: 2.4.8 JVM: 1.7.0_80 Vendor: Oracle Corporation OS: Linux
Upvotes: 2
Views: 680
Reputation: 42224
Groovy adds via DefaultGroovyMethods
a custom compareTo()
methods to Character
and Number
classes that allows you to compare character's ASCII ordinal number against a number value. It means that when you execute:
'z' > 12
in a Groovy Shell, compiler calls:
org.codehaus.groovy.runtime.DefaultGroovyMethods.compareTo((char) 'z', 12)
method instead, because a single character String
is equivalent of Character
. And similar thing happens when you execute:
12 > 'z'
Compiler sees it as:
org.codehaus.groovy.runtime.DefaultGroovyMethods.compareTo(12, (char) 'z')
However, when you execute expression like:
'16' > 16
following method gets executed:
'16'.compareTo(16) // String.compareTo(String other) <-- passing Integer value throws ClassCastException
It happens because String
of size 2 (or more) is not an equivalent of a Character
. This is why you get:
ERROR java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String
because there is no method String.compareTo(Number n)
and compiler does not cast Number
directly to String
in this case. It tries to execute String.compareTo(String other)
method and passing a parameter with a different type than a String
throws ClassCastException
in this case.
If you cast 16
to String
directly, compiler wont complain anymore:
'16' > (String) 16
Hope it helps.
Upvotes: 4