类是对数据的抽象,而类型则是对数据的”分类”,类型比类更“具体”,更“细”一些。
类(class)与类型(type)是两个不一样的概念,类型(type)比类(class)更”具体”,任何数据都有类型。类是面向对象系统里对同一类数据的抽象,在没有泛型之前,类型系统不存在高阶概念,直接与类一一映射,而泛型出现之后,就不在一一映射了。比如定义class List[T] {}
, 可以有List[Int]
和 List[String]
等具体类型,它们的类是同一个List
,但类型则根据不同的构造参数类型而不同。
类型一致的对象它们的类也是一致的,反过来,类一致的,其类型不一定一致。
scala> classOf[List[Int]] == classOf[List[String]] res16: Boolean = true scala> typeOf[List[Int]] == typeOf[List[String]] res17: Boolean = false
在java1.5之后,因为引入了泛型的概念,类型系统变得复杂了,并且因为jvm选择了在运行时采用类型擦拭的做法(兼容性考虑),类型已经不能单纯的用class
来区分了,比如 List<String>
和List<Integer>
的class
都是 Class<List>
,然而两者类型(type)却是不同的。泛型类型的信息要通过反射的技巧来获取,同时java里增加了Type
接口来表达更泛的类型,这样对于 List<String>
这样由类型构造器和类型参数组成的类型,可以通过 Type
来描述;它和 List<Integer>
类型的对应的Type
对象是完全不同的。
在Scala里,类型系统又比java复杂很多,泛型从一开始就存在,还支持高阶的概念(后续会讲述)。所以它没有直接用Java里的Type接口,而是自己提供了一个scala.reflect.runtime.universe.Type
(2.10后)
scala中获取类型(Type):
scala> import scala.reflect.runtime.universe._ scala> class A scala> typeOf[A] res44: reflect.runtime.universe.Type = A
scala中获取类(class):
scala> classOf[A] res52: Class[A] = class AtypeOf
和 classOf
方法接收的都是类型符号(symbol),并不是对象实例
scala> trait T scala> classOf[T] res50: Class[T] = interface T scala> typeOf[T] res51: reflect.runtime.universe.Type = T
对于实例,要获取他的 Class 信息,只有通过 getClass 方法
scala> object O scala> classOf[O] // 这里O是一个单例对象 <console>:14: error: not found: type O
scala> O.getClass res60: Class[_ <: O.type] = class O$
类型一致的对象它们的类也是一致的,反过来,类一致的,其类型不一定一致。
scala> classOf[List[Int]] == classOf[List[String]] res16: Boolean = true scala> typeOf[List[Int]] == typeOf[List[String]] res17: Boolean = false
在jvm里,类的实例数据都是引用形式,而类型没有这个约束,基础类型int
,byte
,char
等就是非引用的。(虽然可以通过int.class
来获取Class对象,但并不能找到有定义class int
的地方,这只是早期java为了统一用class来承载其类型信息的方式)
小结,类型是所有编程语言都有的概念,一切数据都有类型。类更多存在于面向对象语言,非面向对象语言也有“结构体”等与之相似的概念;类是对数据的抽象,而类型则是对数据的”分类”,类型比类更“具体”,更“细”一些。