我有以下类和伴侣对象:
class TestMatch(val i: Int)
object TestMatch{
def apply(i: Int) = new TestMatch(i)
def unapply(tm : TestMatch): Option[Int] = Some(tm.i)
}
现在考虑以下简单程序:
println("isAssignableFrom: " + classOf[TestMatch].isAssignableFrom((tm.getClass)))
println("equality: " + classOf[TestMatch].equals((tm.getClass)))
println("instanceOf:" + TestMatch.isInstanceOf[TestMatch])
打印:
isAssignableFrom: true
equality: true
instanceOf:false
怎么可能?还没有在Java中遇到过这个。
答案 0 :(得分:3)
在每个示例中,您没有提到相同的TestMatch
概念。
classOf[TestMatch]
和instanceOf[TestMatch]
将TestMatch
称为类型。单身人士没有定义类型。TestMatch.something()
是对单例对象TestMatch
现在可能有点令人困惑的是:
object Singleton
println(Singleton.isInstanceOf[Singleton]) // prints true
我猜测当单例是伴侣对象时,Scala会优先考虑该类。
修改强>
正如阿列克谢·罗曼诺夫指出的那样,scala.Singleton
实际上是在Scala SDK中定义的,每个单例对象都会扩展...让我们用另一个名字重新开始:
object MySingleton
println(MySingleton.isInstanceOf[MySingleton])
这不编译,因为单例不定义类型。有一种方法可以编译。
println(MySingleton.isInstanceOf[MySingleton.type]) // true
这就是你如何证明你不是指同一件事。最后的例子,让我们试试
class MyClassWithCompanion
object MyClassWithCompanion
val x = new MyClassWithCompanion
println(MyClassWithCompanion.isInstanceOf[MyClassWithCompanion]) // false
println(MyClassWithCompanion.isInstanceOf[MyClassWithCompanion.type]) // true
println(MyClassWithCompanion.isInstanceOf[x.type] // false
这很微妙,但这就是它的含义:
.type
是应用于实例并返回其类型x.type
只能在x
是某个实例的情况下定义,因此除非此类具有伴随对象,否则MyClass.type
将无法编译。因此,MyClassWithCompanion.type
必然是指伴侣对象(它是一个实例)而不是类本身X
替换X
的实例,这是有道理的,因为它们具有不同的性质。