Scala 相当于 Java java.lang.Class<T> Object

2022-08-31 06:35:34

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

在Java中,对于JPA实体管理器,我可以执行以下操作(帐户是我的实体类):

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

在Scala中,我幼稚的尝试是:

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

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


答案 1

根据“Scala Type System”,

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>

该方法返回 Scala 类型的运行时表示形式。它类似于 Java 表达式 。
当您有一个想要了解其信息的类型时,使用起来很方便,同时便于从该类型的实例中检索相同的信息。classOf[T]T.classclassOf[T]getClass

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

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的返回类型的机票

(詹姆斯·摩尔(James Moore)报告说,这张票是“现在”,即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.Class[T] forSome { 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

答案 2

classOf[Account]在Scala中相当于在Java中。Account.class