Scala 等价于 Java Java.lang. Class < T > Object

这个问题最好用一个例子来解释:

在 Java for a JPA EntityManager 中,我可以执行以下操作(Account 是我的 Entity 类) :

Account result = manager.find(Account.class, primaryKey);

在 Scala 中,我的天真尝试是:

val result = manager.find(Account.class, primaryKey)

但是当我尝试在 Scala 中使用 Account.class时,它似乎不喜欢这样。如何指定 java.lang。Scala 中 Account 类的类对象?

101447 次浏览

Scala 中的 classOf[Account]等价于 Java 中的 Account.class

根据 Scala 类型系统,

val c = new C
val clazz = c.getClass              // method from java.lang.Object
val clazz2 = classOf[C]             // Scala method: classOf[C] ~ C.class
val methods = clazz.getMethods      // method from java.lang.Class<T>

classOf[T]方法返回 Scala 类型的运行时表示,它类似于 Java 表达式 T.class
当您需要关于某个类型的信息时,使用 classOf[T]很方便,而使用 getClass从该类型的实例检索相同的信息很方便。

但是,classOf[T]getClass返回略有不同的值,在 getClass 的情况下,这反映了类型擦除对 JVM 的影响。

scala> classOf[C]
res0: java.lang.Class[C] = class C


scala> c.getClass
res1: java.lang.Class[_] = class C

这就是为什么 跟踪是行不通的:

val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]


val integerClass: Class[Integer] = new Integer(5).getClass //similar error

有一个 关于 getClass返回类型的票据

(詹姆斯 · 摩尔报道,票是“现在”,即2011年11月,两年后,固定。
在2.9.1中,getClass现在可以:

scala> "foo".getClass
res0: java.lang.Class[_ <: java.lang.String] = class java.lang.String

)

回到2009年:

如果 Scala 将 getClass ()的返回值作为 java.lang 处理,那么它将非常有用。类[ T ] for Some { val T: C } ,其中 C 类似于擦除调用 getClass 的表达式的静态类型

它可以让我做类似下面这样的事情: 我想对一个类进行内省,但是不需要类实例。
我还想限制我想要内省的类的类型,所以我使用 Class [ _ < : Foo ]。但是这阻止了我在没有强制转换的情况下使用 Foo.getClass ()来传递 Foo 类。

注意: 关于 getClass,一个可能的解决办法是:

class NiceObject[T <: AnyRef](x : T) {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}


implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)


scala> "Hello world".niceClass
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String