Scala 等价于 Java java.lang.Class<T> Object

Posted

技术标签:

【中文标题】Scala 等价于 Java java.lang.Class<T> Object【英文标题】:Scala equivalent of Java java.lang.Class<T> Object 【发布时间】:2010-11-11 05:42:53 【问题描述】:

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

在 JPA EntityManager 的 Java 中,我可以执行以下操作(Account 是我的 Entity 类):

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

在 Scala 中,我的天真尝试是:

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

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

【问题讨论】:

VonC 已经提供了答案,但请查看我自己在 Scala & Erasure 上的 question/answer。我认为它可能会为你提供一些想法,让你以不同于你正在尝试的方式做事。 【参考方案1】:

根据“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 返回的值略有不同,反映了在 getClass 的情况下类型擦除对 JVM 的影响。

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 年 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>

注意:关于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

【讨论】:

仅供参考,@VonC 提到的票已标记为 22/Jun/11。在 2.9.1 中,getClass 现在可以: scala> "foo".getClass res0: java.lang.Class[_ <: java.lang.string class>【参考方案2】:

Scala 中的classOf[Account] 等价于Java 中的Account.class

【讨论】:

以上是关于Scala 等价于 Java java.lang.Class<T> Object的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.NoSuchMethodError: Scala.Predef$.refArrayOps 在 Spark 作业中使用 Scala

java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: scala/runtime/java8/JFunction1$mcII$

尝试使用 ProGuard 优化 Java+Scala 时出现 java.lang.***Error

java.lang.NoClassDefFoundError: scala/collection/convert/DecorateAsScala 但 pom.xml 中的 scala-library

Spark UserDefinedAggregateFunction:scala.MatchError 0.0(类 java.lang.Double)

java.lang.NoClassDefFoundError: scala/Product$class