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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1135248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:08:55  来源:igfitidea点击:

Scala equivalent of Java java.lang.Class<T> Object

javaclassscala

提问by Kekoa

The question is best explained by an example:

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

In Java for a JPA EntityManager, I can do the following(Account is my Entity class):

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

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

In Scala, my naive attempt is:

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

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

But when I try to use Account.classin Scala, it seems to not like this. How can I specify the java.lang.Class object for the Account class in Scala?

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

采纳答案by VonC

According to "The Scala Type System",

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

The classOf[T]method returns the runtime representation for a Scala type. It is analogous to the Java expression T.class.
Using classOf[T]is convenient when you have a type that you want information about, while getClassis convenient for retrieving the same information from an instance of the type.

classOf[T]方法返回 Scala 类型的运行时表示。它类似于 Java 表达式T.class。当你有一个你想要信息的类型时
使用classOf[T]很方便,而getClass从类型的实例中检索相同的信息很方便。

However, classOf[T]and getClassreturn slightly different values, reflecting the effect of type erasure on the JVM, in the case of 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

That is why the 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

There is a ticket regarding the return type of getClass.

一张关于 的返回类型的票getClass

(James Moorereports that the ticket is "now", ie Nov. 2011, two years later, fixed.
In 2.9.1, getClassnow does:

詹姆斯摩尔报告票是“现在”,即 2011 年 11 月,两年后,固定。
在 2.9.1,getClass现在:

scala> "foo".getClass 
       res0: java.lang.Class[_ <: java.lang.String] = class java.lang.String

)

)

Back in 2009:

回到 2009 年:

It would be useful if Scala were to treat the return from getClass() as a java.lang.Class[T] forSome { val T : C } where C is something like the erasure of the static type of the expression on which getClass is called

It would let me do something like the following where I want to introspect on a class but shouldn't need a class instance.
I also want to limit the types of classes I want to introspect on, so I use Class[_ <: Foo]. But this prevents me from passing in a Foo class by using Foo.getClass() without a cast.

如果 Scala 将 getClass() 的返回值视为 java.lang.Class[T] forSome { val T : C } 其中 C 是类似于 getClass 所在表达式的静态类型的擦除,那将会很有用叫

它会让我做类似下面的事情,我想对一个类进行内省,但不需要类实例。
我也想限制我想反省的类的类型,所以我使用 Class[_ <: Foo]。但这会阻止我通过使用 Foo.getClass() 而没有强制转换来传递 Foo 类。

Note: regarding getClass, a possible workaround would be:

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

回答by Jonathan Graehl

classOf[Account]in Scala is equivalent to Account.classin Java.

classOf[Account]在 Scala 中相当于Account.class在 Java 中。