Java java.lang.Class <T>对象的Scala等价物
这个问题最好用一个例子来解释:
在JPA EntityManager的Java中,我可以执行以下操作(Account是我的实体类):
Account result = manager.find(Account.class, primaryKey);
在斯卡拉,我天真的尝试是:
val result = manager.find(Account.class, primaryKey)
但是当我尝试在Scala中使用Account.class
时,它似乎不喜欢这个。 我怎样才能在Scala中为Account类指定java.lang.Class对象?
根据“ 斯卡拉types系统 ”,
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]
方法返回一个Scalatypes的运行时表示。 它类似于Javaexpression式T.class
。
使用classOf[T]
方便,当你有一个你想要的信息的types,而getClass
方便从types的实例检索相同的信息。
然而,在getClass的情况下, classOf[T]
和getClass
返回稍微不同的值,反映了types擦除对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
的返回types的票证 。
( 詹姆斯·摩尔 ( 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所在的expression式的静态types叫
它会让我做类似于下面的内容,我想在一个类上反思,但不应该需要一个类实例。
我也想限制我想要反思的类的types,所以我使用类[_ <: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
在Scala中的classOf[Account]
相当于Java中的Account.class
。