作者:BrucelLi | 来源:互联网 | 2022-11-28 17:41
从Scala之旅的统一类型文章中的这个方案我认为并且是完全等价的.AnyRef
Object
但是,在Eclipse中检查声明时,我发现了一些有趣的东西:
object ClassTag {
…
val Object : ClassTag[java.lang.Object] = Manifest.Object
…
val AnyRef : ClassTag[scala.AnyRef] = Manifest.AnyRef
…
}
object TypeTag {
…
val AnyRef: TypeTag[scala.AnyRef] = new PredefTypeTag[scala.AnyRef] (AnyRefTpe, _.TypeTag.AnyRef)
val Object: TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe, _.TypeTag.Object)
…
}
一些实验:
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag
println(ClassTag.AnyRef == ClassTag.Object) //true
def getClassTag[V](v: V)(implicit tag: ClassTag[V]) = tag
println(getClassTag[AnyRef](null)) //Object
println(getClassTag[Object](null)) //Object
println(getClassTag(null.asInstanceOf[AnyRef])) //Object
println(getClassTag(null.asInstanceOf[Object])) //Object
println(getClassTag(new AnyRef())) //Object
println(getClassTag(new Object())) //Object
println
println(TypeTag.AnyRef == TypeTag.Object) //false
def getTypeTag[V](v: V)(implicit tag: TypeTag[V]) = tag
println(getTypeTag[AnyRef](null)) //TypeTag[AnyRef]
println(getTypeTag[Object](null)) //TypeTag[Object]
println(getTypeTag(null.asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(null.asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new AnyRef())) //TypeTag[Object]
println(getTypeTag(new Object())) //TypeTag[Object]
println(getTypeTag(new AnyRef().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new AnyRef().asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new Object().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new Object().asInstanceOf[Object])) //TypeTag[Object]
println
println(TypeTag.AnyRef.tpe == TypeTag.Object.tpe) //false
def getType[V](v: V)(implicit tag: TypeTag[V]) = tag.tpe
println(getType[AnyRef](null)) //AnyRef
println(getType[Object](null)) //Object
println(getType(null.asInstanceOf[AnyRef])) //AnyRef
println(getType(null.asInstanceOf[Object])) //Object
println(getType(new AnyRef())) //Object
println(getType(new Object())) //Object
println(getType(new AnyRef().asInstanceOf[AnyRef])) //AnyRef
println(getType(new AnyRef().asInstanceOf[Object])) //Object
println(getType(new Object().asInstanceOf[AnyRef])) //AnyRef
println(getType(new Object().asInstanceOf[Object])) //Object
所以,至少在某些级别的类型信息中Object
并且AnyRef
有所区别.它做了什么?或者它纯粹是一个错误?
1> Seth Tisue..:
你会看到类似的行为与任何类型的别名,我不认为有什么特别Object
/ AnyRef
在你上面的例子.
scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala 2.12.7> class C; type D = C
defined class C
defined type alias D
scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]
scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]
C
并且D
是不同但"等同"的类型.参见SLS 3.5,"类型之间的关系"(https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)