scala object 转Class Scala强制 类型转换
scala object 转Class Scala强制类型转换
asInstanceOf[T]
将对象类型强制转换为T类型。
还是由于泛型存在类型擦除的原因,1.asInstanceOf[String]在运行时会抛出ClassCastException异常,而List(1).asInstanceOf[List[String]]将不会。
}
classOf、isInstanceOf、asInstanceOf三个预定义方法分析
Scala的三个预定义(predefined)方法,我们经常用到;它们用来感觉很简单, 但是里面还是隐藏了一些细节东西,不妨花点时间来分析分析。
先上代码
PredefineTest.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)信息如下:
- 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反编译工具查看对应代码如下:
- 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:
- 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> 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 讨论组里有人问道这样一个问题:
scala> new AnyRef().isInstanceOf[AnyVal]
res0: Boolean = true
大家有兴趣看以看看后面的解答,不过试了scala 2.9, 这种用法 已经被编译器禁止了:
<console>: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:
- 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目前的关注点不在此?
scala object 转Class Scala强制 类型转换的更多相关文章
- scala学习手记35 - 隐式类型转换
先来看一下下面的内容: 2 days "ago" 5 days "from_now" 如上的内容具体应该是什么呢?不过怎么看也不像是代码.不过既然是在学代码,拿 ...
- Beginning Scala study note(3) Object Orientation in Scala
1. The three principles of OOP are encapsulation(封装性), inheritance(继承性) and polymorphism(多态性). examp ...
- 集合框架的类和接口均在java.util包中。 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。
集合框架的类和接口均在java.util包中. 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换.
- Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...
- 《Scala程序设计》暨Scala简介
JVM语言 JVM上的语言越来越多了,从前几年的groovy.Scala和Clojure,现在又听说一门Kotlin.对于前三种语言,groovy算是JVM平台上的动态脚本语言,可以类比Python: ...
- Beginning Scala study note(9) Scala and Java Interoperability
1. Translating Java Classes to Scala Classes Example 1: # a class declaration in Java public class B ...
- Beginning Scala study note(8) Scala Type System
1. Unified Type System Scala has a unified type system, enclosed by the type Any at the top of the h ...
- Beginning Scala study note(6) Scala Collections
Scala's object-oriented collections support mutable and immutable type hierarchies. Also support fun ...
- JavaScript学习10 JS数据类型、强制类型转换和对象属性
JavaScript学习10 JS数据类型.强制类型转换和对象属性 JavaScript数据类型 JavaScript中有五种原始数据类型:Undefined.Null.Boolean.Number以 ...
随机推荐
- Asp.net MVC 如何防止CSRF攻击
什么是CSRF攻击? CSRF(Cross-site request forgery跨站请求伪造,也被称成为"one click attack"或者session riding,通 ...
- Spring框架中IoC(控制反转)的原理(转)
原文链接:Spring框架中IoC(控制反转)的原理 一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作, ...
- nfd指令的详细说明
在eterm上执行NFD:SHAPEK/CA*OW指令,返回如下: LN CXR OW RT FBC/TC RBD MIN/MAX TRVDATE R 01 CA 450.00 U U 00D/00D ...
- JS的scrollIntoView简单使用
scrollIntoView方法滚动当前元素,进入浏览器的可见区域 el.scrollIntoView(); // 等同于el.scrollIntoView(true) el.scrollIntoVi ...
- 判断checkbox选中的个数
直接看例子吧: shippingAddressList 为一个集合 <c:forEach items="${shippingAddressList }" var=" ...
- 艾伦AI研究院发布AllenNLP:基于PyTorch的NLP工具包
https://www.jiqizhixin.com/articles/2017-09-09-5 AllenNLP 可以让你轻松地设计和评估几乎所有 NLP 问题上最新的深度学习模型,并同基础设施一起 ...
- 强化Linux安全的10个技能
1.找出不必要的服务 很明显,服务器上跑的服务,并不是每个都有用的.强烈建议检查并关掉不需要的服务,从而减少风险(多跑一个服务,就可能多几个漏洞). 查询运行在runlevel 3的服务列表: [af ...
- 转: 使用MinGW + Eclipse CDT进行C++开发的配置方法
使用MinGW + Eclipse CDT进行C++开发的配置方法 1 2 3 4 5 6 分步阅读 Eclipse作为开源的IDE,可以用来高效开发Java.C++.C等程序.本文介绍如何在Wind ...
- 转: gcc 指定运行时动态库路径
gcc 指定运行时动态库路径 Leave a reply 由于种种原因,Linux 下写 c 代码时要用到一些外部库(不属于标准C的库),可是由于没有权限,无法将这写库安装到系统目录,只好安装用户目录 ...
- 阿里云centos安装ftp与svn过程
1.下载xshell或者secureCRT 2.登录centos或者服务器 3.安装vsftpd [root@xxx]# yum install vsftpd //安装vsftpd [root@xxx ...