2009-07-16 33 views
156

的问题是最好的例子来说明:斯卡拉相应的Java java.lang.Class中<T>对象

在Java中的JPA EntityManager的,我可以做以下(帐户是我实体类):

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

在斯卡拉,我天真的尝试是:

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

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

+0

VonC已经给出了答案,但看看我自己的[提问/回答(http://stackoverflow.com/ (Scala&Erasure)上的问题/ 1094173 /如何得到周围类型擦除scala-or-why-can-the-type-parameter)。我认为它可能会为您提供想法,以与您尝试的方式不同的方式完成任务。 – 2009-07-16 12:30:14

回答

227

据 “The 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> 

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 

这就是为什么following will not work

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十一月,两年后,固定
在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将是有用的g像getClass被称为的表达式的静态类型的擦除

它会让我做类似下面的事情,我想在一个类上进行内省,但不应该需要一个类实例。
我也想限制我想要反思的类的类型,所以我使用类[_ <: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 
+4

仅供参考,@VonC提及的票据在22/Jun/11被标记为固定。在2.9.1中,getClass现在执行:scala>“foo”.getClass res0:java.lang.Class [_ <:java.lang.String] = class java.lang.String – 2011-11-09 23:03:23

41

classOf[Account] in Scala相当于Java中的Account.class