我刚开始学习groovy,我正在阅读" Groovy in Action"。 在本书中,我遇到了一个声明,无论是声明还是将变量转换为int或Integer类型都无关紧要.Groovy使用引用类型(Integer)。
所以我尝试将 null 值分配给类型为 int 的变量
int a = null
但它给了我以下异常
org.codehaus.groovy.runtime.typehandling.GroovyCastException:无法转换对象' null'与班级' null'上课' int'。试试' java.lang.Integer'代替 在Script1.run(Script1.groovy:2)
然后我尝试将 null 值分配给类型为整数的变量
Integer a = null
它工作得很好。
任何人都可以帮助我理解groovy
行为方式或背后的原因吗?
答案 0 :(得分:4)
核心问题是primitives不能为空。 Groovy用autoboxing伪造出来。
如果您在数字中存储null
值,则无法将其存储在int/long/etc
字段中。将null number
转换为0是不正确的,因为这可能是有效值。 Null
意味着尚未做出任何价值或选择。
int
是primitive type
,不会被视为object
。只有objects
可以有null
值而int
值不能为null
,因为它是值类型而不是引用类型
对于primitive types
,我们有固定的内存大小,即int
我们有4 bytes
而null
仅用于objects
,因为内存大小不是固定的。
所以默认情况下我们可以使用: -
int a = 0
答案 1 :(得分:3)
当调用基元
时,Groovy会一直使用包装器类型int a = 100
assert Integer == a.class
groovy在使用它之前接受int并将其包装到Integer中 但是groovy不能将int值设置为null,因为变量是int(基本类型)而不是Integer。
int a = 100
int b = 200
a + b not int + int, but Integer + Integer
答案 2 :(得分:1)
据我所知,如果使用文字,Groovy会使用包装器类型。例如:
if $::operatingsystem in [ 'Ubuntu', 'Debian' ] {
notify{ 'Debian-type operating system detected': }
} elsif $::operatingsystem in [ 'RedHat', 'Fedora', 'SuSE', 'CentOS' ] {
notify{'RedHat-type operating system detected': }
} else {
notify{'Some other operating system detected': }
}
或
def a = 11 // equivalent to Object a = 11. 11 is an java.lang.Integer
虽然如果在定义中使用特定类型,编译器必须执行转换。
你可以这样做:
assert ['java.lang.Integer'] == [ 11, 22, 33 ]*.class*.name.unique()
但是
def a = 11
a = 'ssss'
给出int a = 11 // or int a
a = 'ssss'
。
这是你在案件中看到的