最好通过一个例子来解释这个问题:
在Java中,对于JPA EntityManager,我可以执行以下操作(Account是我的实体类):
Account result = manager.find(Account.class, primaryKey);
在Scala中,我天真的尝试是:
val result = manager.find(Account.class, primaryKey)
但是当我尝试在Scala中使用Account.class
时,它似乎不喜欢这样。如何在Scala中为Account类指定java.lang.Class对象?
答案 0 :(得分:255)
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
返回的值略有不同,反映了类型擦除对JVM的影响,在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
有ticket regarding the return type of 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 [_&lt;: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
答案 1 :(得分:46)
classOf[Account]
相当于Java中的Account.class
。