Selon " 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>
La classOf[T]
méthode retourne la représentation d'exécution pour un type Scala. C'est analogue à l'expression Java T.class
.
L'utilisation classOf[T]
est pratique lorsque vous avez un type sur lequel vous souhaitez obtenir des informations, tandis qu'elle getClass
est pratique pour récupérer les mêmes informations à partir d'une instance du type.
Cependant, classOf[T]
et getClass
renvoie des valeurs légèrement différentes, reflétant l'effet de l'effacement de type sur la JVM, dans le cas de getClass.
scala> classOf[C]
res0: java.lang.Class[C] = class C
scala> c.getClass
res1: java.lang.Class[_] = class C
C'est pourquoi ce qui suit ne fonctionnera pas :
val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]
val integerClass: Class[Integer] = new Integer(5).getClass //similar error
Il existe un ticket concernant le type de retour degetClass
.
( James Moore rapporte que le ticket est "maintenant", c'est-à-dire novembre 2011, deux ans plus tard, corrigé.
En 2.9.1, fait getClass
maintenant:
scala> "foo".getClass
res0: java.lang.Class[_ <: java.lang.String] = class java.lang.String
)
De retour en 2009:
Ce serait utile si Scala traitait le retour de getClass () comme un java.lang.Class [T] forSome {val T: C} où C est quelque chose comme l'effacement du type statique de l'expression sur laquelle getClass est appelé
Cela me permettrait de faire quelque chose comme ce qui suit où je veux introspecter une classe mais ne devrait pas avoir besoin d'une instance de classe.
Je souhaite également limiter les types de classes sur lesquelles je souhaite effectuer une introspection, j'utilise donc Class [_ <: Foo]. Mais cela m'empêche de passer dans une classe Foo en utilisant Foo.getClass () sans cast.
Remarque: concernant getClass
, une solution de contournement possible serait:
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