我一直在玩Groovy并遇到了这个有趣的事情.
检查长整数列表是否包含特定数字在检查整数值时有效,但在检查长值时则无效.
List<Long> list = [5, 7, 3]
println (5 in list) // true
println (5L in list) // false
int i = 5
long l = 5
println (i in list) // true
println (l in list) // false
Integer i2 = 5
Long l2 = 5
println (i2 in list) // true
println (l2 in list) // false
我在https://groovyconsole.appspot.com/上运行了这段代码.这对我来说似乎很糟糕(或者至少非常反直觉).我希望在List.contains的实现中有一些问题,它使用的是什么比较运算符?
我可以解决这个问题,但我想知道是否有一些我缺少的东西,或者这是否真的是预期的行为?
最佳答案 这是因为
type erasure,即运行时没有类型信息.由于groovy是
dynamic language(使用元对象协议的方法调用的动态调度等),默认情况下没有类型检查/静态编译.
所以你的groovy代码大致相当于这个groovy代码:
def list = [5, 7, 3]
// no type checking by default, so generics types does not matter due to type erasure
[...]
或者这个pre-generics java代码:
List list = new ArrayList();
list.add(5);
list.add(7);
list.add(3);
System.out.println(list.contains(5)); // true
System.out.println(list.contains(5L)); // false
[...]
如果你在java中编译它(更好用-Xlint)你会得到经典的Unchecked Error Messages.
从groovy 2.0开始,您可以使用@ groovy.transform.TypeChecked / @ groovy.transform.CompileStatic打开类型检查/静态编译(静态编译触发器也可以进行类型检查):
@groovy.transform.CompileStatic
class Test {
static main(args) {
List<Long> list = [5, 7, 3]
println (5 in list) // true
println (5L in list) // false
int i = 5
long l = 5
println (i in list) // true
println (l in list) // false
Integer i2 = 5
Long l2 = new Long(5)
println (i2 in list) // true
println (l2 in list) // false
}
}
这样您就会收到编译错误:
[Static type checking] - Incompatible generic argument types. Cannot assign java.util.List <java.lang.Integer> to: java.util.List <Long>