类和类型

List<String>和List<Int>类型是不一样的,但是jvm运行时会采用泛型擦除。导致List<String>和List<Int>都是Class<List>.为了得到正确的类型,需要通过反射。

泛型擦除

Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。泛型擦除是为了兼容jdk1.5之前的jvm,在这之前是不支持泛型的。

classOf与getClass方法的差异

scala> class  A
scala> val a = new A scala> a.getClass
res2: Class[_ <: A] = class A scala> classOf[A]
res3: Class[A] = class A

上面显示了两者的不同,getClass 方法得到的是 Class[A]的某个子类,而 classOf[A] 得到是正确的 Class[A],但是去比较的话,这两个类型是equals为true的

classOf和getClass

classOf获取运行时的类型。classOf[T] 相当于 java中的T.class

  val listClass = classOf[List[_]]
* // listClass is java.lang.Class[List[_]] = class scala.collection.immutable.List
val mapIntString = classOf[Map[Int,String]]
* // mapIntString is java.lang.Class[Map[Int,String]] = interface scala.collection.immutable.Map
* }}}

而getClass:

scala> class  A
scala> val a = new A scala> a.getClass
res2: Class[_ <: A] = class A scala> classOf[A]
res3: Class[A] = class A

上面显示了两者的不同,getClass 方法得到的是 Class[A]的某个子类,而 classOf[A] 得到是正确的 Class[A],但是去比较的话,这两个类型是equals为true的

scala> a.getClass  == classOf[A]
res13: Boolean = true

这种细微的差别,体现在类型赋值时,因为java里的 Class[T]是不支持协变的,所以无法把一个 Class[_ < : A] 赋值给一个 Class[A]

scala> val c:Class[A] = a.getClass
<console>:: error: type mismatch;

类(class)与类型(type)是两个不一样的概念
(在java里因为早期一直使用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

ClassTag

ClassTag[T]保存了被泛型擦除后的原始类型T,提供给运行时的。

scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*)
mkArray: [T](elems: T*)(implicit evidence$: scala.reflect.ClassTag[T])Array[T]

TypeTag

TypeTag则保存所有具体的类型

import scala.reflect.runtime.universe._
def paramInfo[T](x: T)(implicit tag: TypeTag[T]): Unit = {
val targs = tag.tpe match { case TypeRef(_, _, args) => args }
println(s"type of $x has type arguments $targs")
}
scala> paramInfo()
type of has type arguments List()
scala> paramInfo(List(, ))
type of List(, ) has type arguments List(Int)

可以看到,获取到的类型是具体的类型,而不是被擦除后的类型List(Any)

Scala的类与类型的更多相关文章

  1. 泛函编程(4)-深入Scala函数类

    既然是泛函编程,多了解一下函数自然是免不了的了: 方法(Method)不等于函数(Function) 方法不是函数但可以转化成函数:可以手工转换或者由编译器(compiler)在适当的情况下自动转换. ...

  2. scala学习-类与对象

    类 / 对象 [<快学Scala>笔记] 一.类 1.Scala中的类是公有可见性的,且多个类可以包含在同一个源文件中: class Counter{ private var value ...

  3. Scala函数---既存类型

    语法: Type ::= InfixType ExistentialClauses ExistentialClauses ::= „forSome‟ „{‟ ExistentialDcl {semi ...

  4. Programming In Scala笔记-第十七章、Scala中的集合类型

    本章主要介绍Scala中的集合类型,主要包括:Array, ListBuffer, Arraybuffer, Set, Map和Tuple. 一.序列 序列类型的对象中包含多个按顺序排列好的元素,可以 ...

  5. Scala:类,对象和特征(接口)

    http://blog.csdn.net/pipisorry/article/details/52902609 Scala类和对象 类是对象的抽象,而对象是类的具体实例.类是抽象的,不占用内存,而对象 ...

  6. Scala的类层级讲解

    Scala的类层级 Scala里,每个类都继承自通用的名为Any的超类. 因为所有的类都是Any的子类,所以定义在Any中的方法就是"共同的"方法:它们可以被任何对象调用. Sca ...

  7. Scala进阶之路-Scala中的高级类型

    Scala进阶之路-Scala中的高级类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类型(Type)与类(Class)的区别 在Java里,一直到jdk1.5之前,我们说 ...

  8. Scala学习之路 (六)Scala的类、对象、继承、特质

    一.类 1.类的定义 scala语言中没有static成员存在,但是scala允许以某种方式去使用static成员这个就是伴生机制,所谓伴生,就是在语言层面上,把static成员和非static成员用 ...

  9. Scala进阶之路-Scala特征类与unapply反向抽取

    Scala进阶之路-Scala特征类与unapply反向抽取 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala特征类分析 1>.Unit 答:用于定义返回值类型, ...

随机推荐

  1. Kafka中Producer端封装自定义消息

    我们知道KeywordMessage就是被kafka发送和存储的对象.所以只需要模拟出这个就可以发送自定义消息了. 比如我需要将用户的id,user,age,address和访问ip和访问date记录 ...

  2. linux 启动时文件系统错误

    由于我把/dev/VolGroup00/lvData写在了/etc/fstab中,后面又把这个lv给删除了,导致出现下面开机启动的错误: 解决办法: 1.进入单用户模式下,当修改/etc/fstab时 ...

  3. C语言各种存储模式的区别?最常用的存储模式有哪些?

    DOS用一种段地址结构来编址计算机的内存,每一个物理内存位置都有一个可通过段地址一偏移量的方式来访问的相关地址.为了支持这种段地址结构,大多数C编译程序都允许你用以下6种存储模式来创建程序: ---- ...

  4. INSTALL_FAILED_INVALID_APK

    在项目中无意中把APP只写成了 xxx  没有xxx.xxx.xxx  掉坑里了,找了好久,给大家提不醒

  5. VC项目程序运行时设置指定目录读取Dll

    方法一: 选择当前工程,右击"Properties" -> "Configuration Properties" -> "Debuggin ...

  6. LeetCode——House Robber

    Description: You are a professional robber planning to rob houses along a street. Each house has a c ...

  7. gvim编辑器_vimrc文件

    set nocompatiblesource $VIMRUNTIME/vimrc_example.vimsource $VIMRUNTIME/mswin.vimbehave mswin set dif ...

  8. 【BZOJ1879】[Sdoi2009]Bill的挑战 状压DP

    [BZOJ1879][Sdoi2009]Bill的挑战 Description Input 本题包含多组数据.  第一行:一个整数T,表示数据的个数.  对于每组数据:  第一行:两个整数,N和K(含 ...

  9. Android 动态设置控件高度

    TextView textView= (TextView)findViewById(R.id.textview); LinearLayout.LayoutParams linearParams =(L ...

  10. 【Android】Android中不同手机分辨率适配问题

    在项目开发的过程中,同一个布局对应不同的手机会显示出不同的效果.导致这个现象产生的原因是不同手机的分辨率不同.在android sdk提供的帮助文档中,我们可以看到各种手机的分辨率和对应的屏大小.QV ...