質問は例によって最もよく説明されます:
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オブジェクトを指定するにはどうすればよいですか?
「 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 expressionT.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
ScalaのclassOf[Account]
は、JavaのAccount.class
と同等です。