asInstanceOf[T]

将对象类型强制转换为T类型。

还是由于泛型存在类型擦除的原因,1.asInstanceOf[String]在运行时会抛出ClassCastException异常,而List(1).asInstanceOf[List[String]]将不会。

packageresti.web

importorg.springframework.beans.factory.annotation.Autowired

importorg.springframework.security.core.context.SecurityContextHolder

importorg.springframework.stereotype.Controller

importorg.springframework.ui.Model

importorg.springframework.web.bind.annotation.RequestMapping

importresti.domain.HttpApi

importresti.service.HttpApiRepository

importorg.springframework.security.core.userdetails.UserDetails

importorg.springframework.web.bind.annotation.RequestMethod

@Controller

@RequestMapping(Array("/product"))

classProductController @Autowired() (privatevalhttpApiRepository: HttpApiRepository) {

@RequestMapping(method = Array(RequestMethod.GET))

def list(model: Model) = {

// get current user

val userDetails = SecurityContextHolder.getContext().getAuthentication().getPrincipal().asInstanceOf[UserDetails]

model.addAttribute("currentUser", userDetails.getUsername)

model.addAttribute("products", httpApiRepository.findProducts())

"product/list"

}

}

classOf、isInstanceOf、asInstanceOf三个预定义方法分析

Scala的三个预定义(predefined)方法,我们经常用到;它们用来感觉很简单,

但是里面还是隐藏了一些细节东西,不妨花点时间来分析分析。

先上代码

PredefineTest.scala

Scala代码 

object PredefineTest{

def main(args: Array[String]):Unit = {

val c : Char = 97.asInstanceOf[Char]

"hello".asInstanceOf[String]

1.asInstanceOf[Long]

val it: Seq[String] = List("a", "b")

it.asInstanceOf[List[String]]

"hello".isInstanceOf[String]

classOf[String]

}

}

使用scalac -Xprint:cleanup PredefineTest.scala,Scala编译器输出的main方法体内代码的抽象语法树(AST)信息如下:

Scala代码 

val c: Char = 97.toChar();

("hello": java.lang.String);

1.toLong();

val it: Seq = immutable.this.List.apply(scala.this.Predef.wrapRefArray(Array[java.lang.String]{"a", "b"}.$asInstanceOf[Array[java.lang.Object]]()));

it.$asInstanceOf[List]();

"hello".$isInstanceOf[java.lang.String]();

{

classOf[java.lang.String];

()

}

使用jd反编译工具查看对应代码如下:

Java代码 

char c = (char)97;

"hello";

1;

Seq it = List..MODULE$.apply(Predef..MODULE$.wrapRefArray((Object[])new String[] { "a", "b" }));

((List)it);

("hello" instanceof String);

String.class;

结合上面源码来进行分析

classOf[T]

获取类型T的Class对象

classOf方法定义在scala.Predef object:

Scala代码 

object Predef extends LowPriorityImplicits {

def classOf[T]: Class[T] = null

...

classOf的注释翻译过来的意思是:返回类型的运行时呈现状态。这是一个存根方法。实际的实现是由编译器填补(自动生成)。

Predef

object是默认导入的,所以classOf方法相当于一个全局方法。

isInstanceOf[T]

判断对象是否为T类型的实例。

isInstanceOf和asInstanceOf

由scala.Any类定义,Scala类层级的根类;其中class scala.AnyRef

继承自Any,是所有应引用类型的基类;trait scala.AnyVal

也继承自Any,是所有基本类型的实现的trait。所以所有对象都自动拥有isInstanceOf和asInstanceOf这两个方法。

特别注意的是 Any 和AnyRef

这两个类属于“编译时类型”(虚拟类型?),不存在于运行时。所以这两者在Scala中都未提供源码,其语义由编译器在编译时构建。

再看一下例子:

Scala代码 

scala> 1.isInstanceOf[String]

res0: false

scala> List(1).isInstanceOf[List[String]]

res0: true

由于Scala像Java一样泛型存在类型擦除的原因,List(1).isInstanceOf[List[String]]及相当于List(1).isInstanceOf[List[_]],

List(1) 是List的实例.

asInstanceOf[T]

将对象类型强制转换为T类型。

还是由于泛型存在类型擦除的原因,1.asInstanceOf[String]在运行时会抛出ClassCastException异常,而List(1).asInstanceOf[List[String]]将不会。

在scala 讨论组里有人问道这样一个问题:

”I expect "new AnyRef().isInstanceOf[AnyVal]" to be false, but I

get true instead“

scala> new AnyRef().isInstanceOf[AnyVal]

res0: Boolean = true

大家有兴趣看以看看后面的解答,不过试了scala 2.9, 这种用法

已经被编译器禁止了:

scala> new AnyRef().isInstanceOf[AnyVal]

:8: error: type AnyVal

cannot be used in a type pattern or isInstanceOf test

new AnyRef().isInstanceOf[AnyVal]

还有,值得提一下的一个小细节就是,通过观察编译输出的AST,

知道对于在基本类型如Int等的对象上调用asInstanceOf[T],

Scala会将其转换为调用相应的toT方法, 如 1.asInstanceOf[Char], 就会转换为 97.toChar,

其中toChar 定义在 scala.Int:

Scala代码 

final class Int extends AnyVal {

...

def toChar: Char = sys.error("stub")

...

}

而后, Scala编译器会进一步将其编译成与“(char)97”相同的字节码。

结论

总而言之,我们把classOf[T]看成Java里的T.class,

obj.isInstanceOf[T]看成 obj instanceof T,

obj.asInstanceOf[T]看成(T)obj就对了。scala为我们提供了语法糖,但也免不了类型擦除问题的影响。

值得探讨的地方

个人感觉,Scala对Java的类这一块没什么增强,

比如像Ruby一样类文字量也是对象(虽然理解起来有点绕,但是更能体现面向对象一致性),就不用classOf[T]这样添足的写法,而是:object.getClass

== String 。如此,是不是JVM的限制,还是Scala目前的关注点不在此?

java object强制类型转换_scala object 转Class Scala强制类型转换相关推荐

  1. java long转object_Java 类型转换以及Object转成其他类型

    Object转int int count=(int)map.get("count") int count=Integer.parseInt((String)map.get(&quo ...

  2. Java泛型中? 和 ? extends Object的异同分析

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 刘一手 来源 | 公众号「锅外的大佬」 Jav ...

  3. java api class_Java API:Object class

    Java API:Object class 首先简单的介绍一下Object类. java.lang.Object java.lang包使用的时候,不用显示导入,由编译器自动导入. Objec(即对象类 ...

  4. Cause: java.sql.SQLException: Invalid parameter object type. Expected 'com.jd.sns.biz.api.domain.Plu

    java.sql.SQLException: Invalid parameter object type. Expected 'java.util.Map' but found 'java.lang. ...

  5. java的object有show_Java中 Object的方法

    Java中 Object的方法 构造方法摘要 Object() 方法摘要 protected Object clone() 创建并返回此对象的一个副本. boolean equals(Object o ...

  6. Java的超类/基类Object

    文章目录 简介 主要方法 equals 简介 所有的类都继承了 Object,即 Object 是所有类的父类,所以所有的 Java 类都继承了 Object 的所有方法. 比如你写一个类如下: pu ...

  7. java面试题27 java中下面哪些是Object类的方法()

    java面试题27 java中下面哪些是Object类的方法() A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果,蒙蔽树下你和我.遇到这种题,我 ...

  8. 关于java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to 实体类

    由于业务逻辑的复杂,有些sql语句写法hql不支持,所以hibernate查询直接用了sql原生查询,由于数据结果根据四个表查询出来,所以无法使用方法.addEntity(XXXXXXX.class) ...

  9. java中clone方法_Java Object clone()方法– Java中的克隆

    java中clone方法 Cloning is the process of creating a copy of an Object. Java Object class comes with na ...

最新文章

  1. TensorFlowSharp入门使用C#编写TensorFlow人工智能应用
  2. mysql数据库表删了重建error_数据库内核月报 - 2015 / 09-MySQL · 捉虫动态 · 建表过程中crash造成重建表失败-阿里云开发者社区...
  3. mysql的三大引擎是什么_MySQL常用三大存储引擎
  4. WebClient DownloadFile 用法
  5. 【Java】多线程SynchronizedVolatile、锁升级过程 - 预习+第一天笔记
  6. Leetcode--102. 二叉树的层次遍历
  7. NYOJ-寻找最大数(贪心)
  8. cxf webservice:异常SOAPFaultException: Unexpected wrapper element found解决
  9. 常用的delphi 第三方控件
  10. 搜索自己博客中的文章
  11. 轻松绘制图像图形!且看Aspose新产品GDI +图形处理API-Aspose.Drawing如何操作!
  12. python爬虫爬取网易云热歌榜top200
  13. 果园树枝分割论文汇总
  14. 929. 独特的电子邮件地址(简单,字符串)(12.20)
  15. 浅谈自然辩证在现代科学领域的作用
  16. 个人关于web开发浅尝辄止,web开发概览
  17. Flume 以twitter为source,kafka为channel,hdfs为sink,再用spark streaming 读kafka topic
  18. HEAD: HEtero-Assists Distillation for Heterogeneous Object Detectors
  19. java牙科诊所管理系统_基于jsp的私人牙科诊所管理系统-JavaEE实现私人牙科诊所管理系统 - java项目源码...
  20. 什么样的企业会上BI系统?

热门文章

  1. JQuery .net WebService 参数必须一致
  2. VM虚拟机显示不能铺满问题
  3. python函数-函数进阶
  4. string 大小写转换
  5. python模块;opencv安装
  6. 解决express video 手机无法播放的问题
  7. node模块函数图解
  8. (译)利用ASP.NET加密和解密Web.config中连接字符串
  9. ios程序 调试log宏的添加
  10. SMO写的查看数据库信息的代码