list<string>和list<int>类型是不一样的,但是jvm运行时会采用泛型擦除。导致list<string>和list<int>都是class<list>.为了得到正确的类型,需要通过反射。
java中的泛型基本上都是在编译器这个层次来实现的。在生成的java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。泛型擦除是为了兼容jdk1.5之前的jvm,在这之前是不支持泛型的。
上面显示了两者的不同,getclass 方法得到的是 class[a]的某个子类,而 classof[a] 得到是正确的 class[a],但是去比较的话,这两个类型是equals为true的
classof获取运行时的类型。classof[t] 相当于 java中的t.class
而getclass:
这种细微的差别,体现在类型赋值时,因为java里的 class[t]是不支持协变的,所以无法把一个 class[_ < : a] 赋值给一个 class[a]
<code>类(class)与类型(type)是两个不一样的概念</code>
(在java里因为早期一直使用class表达type,并且现在也延续这样的习惯);类型(type)比类(class)更”具体”,任何数据都有类型。类是面向对象系统里对同一类数据的抽象,在没有泛型之前,类型系统不存在高阶概念,直接与类一一映射,而泛型出现之后,就不在一一映射了。比如定义class list[t] {}, 可以有list[int] 和 list[string]等具体类型,它们的类是同一个list,但类型则根据不同的构造参数类型而不同。
类型一致的对象它们的类也是一致的,反过来,类一致的,其类型不一定一致。
classtag[t]保存了被泛型擦除后的原始类型t,提供给运行时的。
typetag则保存所有具体的类型
可以看到,获取到的类型是具体的类型,而不是被擦除后的类型list(any)
<a target="_blank" href="http://hongjiang.info/scala-type-system-classof-and-getclass/">http://hongjiang.info/scala-type-system-classof-and-getclass/</a>
<a target="_blank" href="http://hongjiang.info/scala-type-and-class/">http://hongjiang.info/scala-type-and-class/</a>
<a target="_blank" href="http://www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.reflect.classtag">http://www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.reflect.classtag</a>
<a target="_blank" href="http://blog.csdn.net/lonelyroamer/article/details/7868820">http://blog.csdn.net/lonelyroamer/article/details/7868820</a>