谈谈1.getClass
Ruby是纯面向对象语言,1,1.0这些基本类型在Ruby中也是对象。如:
> 1.class
=> Fixnum
> "hello".class
=> String
> 1.0.class
=> Float
Scala 也是面向对象(与函数式结合的)语言。在Scala 2.9.0 下, 如果我们试图 1.getClass,期待会返回java.lang.Class[Int],实际上却报错了:
$ scala
Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
scala> 1.getClass
<console>:8: error: type mismatch;
found : Int(1)
required: ?{val getClass: ?}
Note: primitive types are not implicitly converted to AnyRef.
You can safely force boxing by casting x.asInstanceOf[AnyRef].
1.getClass
^
解读一下编译器提示的错误:
1 是基本类型, 基本类型(值类型AnyVal)没有定义getClass方法,只有引用类型(AnyRef)定义,可以强制进行装箱,通过x.asInstanceOf[AnyRef]的方式:
好吧, 按照提示做一遍:
scala> 1.asInstanceOf[AnyRef].getClass
res0: java.lang.Class[_ <: AnyRef] = class java.lang.Integer
好像是那么回事了, 通过这一篇介绍的方法:scalac -Xprint:cleanup X.scala,找到 1.asInstanceOf[AnyRef].getClass对应抽象语法树AST是:
scala.Int.box(1).getClass();
扣源代码,调用了Int伴生对象的box方法,定义如下:
object Int extends AnyValCompanion {
...
def box(x: Int): java.lang.Integer = java.lang.Integer.valueOf(x)
...
}
可见,box的作用很明确,将Int的装箱为java.lang.Integer。
到这里,好像一切都顺理成章了。但是仔细想一想,scala.Predef 定义了Int到java.lang.Integer隐式转换函数:
implicit def int2Integer(x: Int) = java.lang.Integer.valueOf(x)
这里1.getClass方法为什么不通过这个隐式转换后调用呢? 试试java.lang.Integer.intValue()方法实施到1上,看什么效果:
scala> 1.intValue()
res1: Int = 1
有点奇怪吧?? 试了一下,Scala 2.8 版也有此问题。
难道对Scala对基本类型调用getClass 做了特别处理?(这里还没想清楚,求解释)
最近(2011-07-25)Scala发布了 2.9.1 RC1版, 推上有人提到 1.getClass这个问题。马上试试:
$ scala
Welcome to Scala version 2.9.1.RC1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
scala> 1.getClass
res0: java.lang.Class[Int] = int
scala> (1.0).getClass
res1: java.lang.Class[Double] = double
scala> true.getClass
res2: java.lang.Class[Boolean] = boolean
看到没, 如期望的一样,对基本类型调用getClass, 能正常的返回其对应的类Class信息了。
到底Scala 2.9.1 做什么什么改进呢?
经过一番探寻, 得知:
Any根类新定义了getClass这个抽象方法方法,看看以下类型体系:
Any
├── AnyRef
└── AnyVal
├── Boolean (scala.Boolean)
├── Char
├── Int
└── Unit
明显的, Int类实现了这个getClass方法, 不用去做装箱或隐式转换Magic处理了。
这样处理是很自然的, 也觉得Scala 2.9.1面向对象变得更“纯”了。
(注:Any是“编译期类型”,看不到源码的。通过文档看看scala2.9.0跟Scala主干的对比吧:
http://www.scala-lang.org/api/current/index.html#scala.Any
http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.Any)
分享到:
相关推荐
1. Class literal (`ClassName.class`) 提供静态访问类的元数据,并可用于创建类的新实例。 2. `instance.getClass()` 返回运行时对象的确切类型,提供了多态场景下的类型信息。 3. `Class.forName(String className...
文章目录每日一考和复习反射反射的应用:动态代理Java 8 的其他新特性Lambda表达式函数式(Functional)接口方法引用与构造器引用方法引用构造器调用强大的Stream APIStream的实例化中间操作终止操作...谈谈你对Class类
1. 悲观锁: 悲观锁在进行操作前假定会有其他并发操作对数据进行修改,因此在开始操作之前会先锁定资源,以确保操作的原子性。然而,Redis本身并不直接支持悲观锁,因为其主要设计用于高读取性能的场景,而锁的引入...
接下来,我们谈谈Hibernate,它是一个ORM(Object-Relational Mapping)框架,简化了数据库操作。在Hibernate中,你可以定义实体类(对应数据库表),并通过HQL(Hibernate Query Language)或JPQL(Java ...
Field valuesField = exifDirectory.getClass().getDeclaredField("values"); valuesField.setAccessible(true); List<ImageMetaValue> values = (List) valuesField.get(exifDirectory); for (ImageMetaValue ...
接下来,我们谈谈如何在连接断开后实现自动重连。在实际网络环境中,由于各种原因(如网络抖动、服务器重启等),连接可能会中断。为了保证服务的连续性,Netty 提供了重连功能。这通常通过 ChannelHandler 来实现,...
Method method = worker.getClass().getMethod("doTask", CallbackInterface.class); method.invoke(worker, worker); // 使用反射调用doTask方法,传入worker自身作为回调 } } ``` 在这个示例中,`Main`类通过...
1. **源代码阶段**: 我们首先编写Java源代码,例如创建一个名为`Cat`的类,包含名字、年龄属性以及构造方法和`meow`方法。然后通过`javac`编译器将源代码编译成字节码文件(`.class`)。 2. **字节码阶段**: ...
FXMLLoader loader = new FXMLLoader(getClass().getResource("your.fxml"), ResourceBundle.getBundle("your.properties", Locale.getDefault())); loader.setCharset(Charset.forName("UTF-8")); ``` 5. 如果...
什么是SOA,谈谈你的SOA的理解。serviceorientiedarchitecture?** - SOA(Service-Oriented Architecture)是一种面向服务的架构模型,它将应用程序的不同功能单元通过服务接口和服务协议联系起来。 - 服务接口...
17. 谈谈你对`static`关键词的理解。 - `static`关键词有多种用途: - 定义静态变量和方法,它们属于类而不是类的实例。 - 创建静态初始化块,用于类加载时执行初始化代码。 - 定义静态内部类,此类与外部类的...
首先,我们来谈谈Object类。Object类是所有Java类的顶级父类,无论是自定义的类还是Java API中的任何类,它们最终都会直接或间接地继承自Object类。因此,每个Java类至少拥有Object类提供的方法。Object类中包含了...
1. 获取Class对象:可以通过Class.forName()方法,或者对象的getClass()方法,或者类的.class属性来获取。 2. 创建对象:使用Class对象的newInstance()方法(要求有无参构造器)或Constructor的newInstance()方法...
1、谈谈你对Struts的理解。 117 2、谈谈你对Hibernate的理解。 118 3、AOP的作用。 118 4、你对Spring的理解。 118 5、谈谈Struts中的Action servlet。 120 6、Struts优缺点 优点: 1. 实现MVC模式,结构清晰,使...
1、谈谈你对Struts的理解。 128 2、谈谈你对Hibernate的理解。 128 3、AOP的作用。 129 4、你对Spring的理解。 129 5、谈谈Struts中的Action servlet。 131 6、Struts优缺点 优点: 1. 实现MVC模式,结构清晰,使...
1、谈谈你对Struts的理解。 117 2、谈谈你对Hibernate的理解。 118 3、AOP的作用。 118 4、你对Spring的理解。 118 5、谈谈Struts中的Action servlet。 120 6、Struts优缺点 优点: 1. 实现MVC模式,结构清晰,...
1、谈谈你对Struts的理解。 117 2、谈谈你对Hibernate的理解。 118 3、AOP的作用。 118 4、你对Spring的理解。 118 5、谈谈Struts中的Action servlet。 120 6、Struts优缺点 优点: 1. 实现MVC模式,结构清晰,使...
1、谈谈你对Struts的理解。 117 2、谈谈你对Hibernate的理解。 118 3、AOP的作用。 118 4、你对Spring的理解。 118 5、谈谈Struts中的Action servlet。 120 6、Struts优缺点 优点: 1. 实现MVC模式,结构清晰,使...