在Java里,一直到JDK1.5之前,一个对象的类型(type)都与它的class是一一映射的,通过获取它们的class对象,比如String.class、int.class、obj.getClass()等,就可以判断它们的类型(type)是不是一致的。
而到了JDK1.5之后,因为引入了泛型的概念,类型系统变得复杂了,并且因为JVM选择了在运行时采用类型擦拭的做法(兼容性考虑),类型已经不能单纯用class来区分了,比如List<String>和List<Integer>的class都是Class<List>,然而两者的类型(type)却是不同的。泛型类型的信息要通过反射的技巧来获取,同时Java里增加了Type接口来表达更泛的类型,这样对于List<String>这样由类型构造器和类型参数组成的类型,可以通过Type来描述;它和List<Integer>类型对应的Type对象是完全不同的。
和Java的类型系统相比,Scala的类型系统虽然也是静态类型系统,但由于具备类型推断等,在实际使用上是非常灵活的,对应的Java的静态类型系统则不太灵活,使用起来比较困难;其次,Scala带有模式匹配,可以非常灵活地恢复类型信息。虽然Scala的类型系统在使用上更加灵活,而且相比Java的类型系统也更加丰富(部分类型信息可以参考本书的第7章高级类型的内容)。同时Scala没有直接用Java里的Type接口,而是自己提供了一个scala.reflect.runtime.universe.Type(2.10后)。虽然如此,在Scala中仍然存在类型擦除相关的问题。(www.daowen.com)
Scala中提供了ClassTag特质,该特质用于存储被擦除的T类型的类信息,极大地方便了在编译期时对象的实例化。ClassTag相比TypeTag是比较弱的,ClassTag包含了T运行时的类信息(class),对应在TypeTag中则包含了T的所有静态类型信息。
需要注意的是,类型擦除通常用类来翻译Class,用Type来翻译类型信息。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。