Groovy中List<List<Integer>>可存入Integer元素的异常行为原因咨询
Groovy显式声明泛型后仍允许存入不匹配类型的技术原因
- 底层依赖JVM的泛型擦除机制
泛型是JVM提供的编译期语法糖,运行阶段所有泛型参数都会被擦除为上限类型(无明确上限则为Object)。你声明的List<List<Integer>>在运行时本质就是原生List,只会存储Object类型元素,本身没有能力校验元素是否符合List<Integer>的类型约束,这是所有基于JVM的语言共有的底层限制。 - Groovy默认动态模式关闭了静态类型校验
和Java默认开启严格的静态编译校验不同,Groovy默认运行在动态类型模式下,即便你为变量显式指定了带泛型的静态类型,编译器也不会在编译阶段检查集合操作的泛型类型匹配性:你调用add(1)传入Integer类型时,不会触发任何编译错误,自然能正常存入列表、读取运行。
如果要启用严格的泛型约束校验,只需要在类或者方法上添加@CompileStatic注解开启静态编译,此时编译器会直接在编译阶段抛出类型不匹配错误,阻止不符合泛型约束的代码编译通过,示例如下:
// 加了静态编译注解的代码会直接编译报错 @CompileStatic static void main(String[] args) { List<List<Integer>> list = [] list.add(1) // 编译错误:Expected type List<Integer>, got Integer println(list.get(0)) }
- 补充说明:你提到的Groovy支持异构列表的特性和这个问题无关,异构列表是动态类型下列表元素可以为任意类型的表现,本质还是因为默认没有开启静态类型校验,运行时泛型擦除没有类型限制导致的。
内容的提问来源于stack exchange,提问作者Youssef Khloufi
相关产品推荐
相关产品推荐

