web-dev-qa-db-ja.com

Scala Java java.lang.Class <T>オブジェクトと同等

質問は例によって最もよく説明されます:

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オブジェクトを指定するにはどうすればよいですか?

180
Kekoa

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

以下は機能しません

val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]

val integerClass: Class[Integer] = new Integer(5).getClass //similar error

getClassの戻り型に関するチケット があります。

James Moore は、チケットが「今」、つまり2年後の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クラスを渡すことができなくなります。

注: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
258
VonC

ScalaのclassOf[Account]は、JavaのAccount.classと同等です。

48
Jonathan Graehl