这个问题最好用一个例子来解释:
在 JPA EntityManager 的 Java 中,我可以执行以下操作(帐户是我的实体类):
Account result = manager.find(Account.class, primaryKey);
在 Scala 中,我天真的尝试是:
val result = manager.find(Account.class, primaryKey)
但是当我尝试Account.class在 Scala 中使用时,它似乎不喜欢这样。如何在 Scala 中为 Account 类指定 java.lang.Class 对象?
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]
T.class
classOf[T]``getClass
但是,在 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
有一张关于返回类型的票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.Class[T] forSome { val T : C } 将很有用,其中 C 类似于擦除 getClass 所在的表达式的静态类型叫 它可以让我做类似下面的事情,我想对一个类进行自省但不应该需要一个类实例。 我还想限制我想反省的类的类型,所以我使用 Class[_ <: Foo]。但这阻止了我通过使用 Foo.getClass() 而不进行强制转换来传递 Foo 类。
如果 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