How can I get Class[T] from an implicit ClassTag[T]?
class, reflection, scala, scala-2.10
Solution
Here is the ticket on `getClass` and the linked forum discussion in which Odersky speculates:
You could also use a cast.
Here is the duplicate ticket where `getClass` is fixed. `5.getClass` also casts:
/** Return the class object representing an unboxed value type,
* e.g. classOf[int], not classOf[java.lang.Integer]. The compiler
* rewrites expressions like 5.getClass to come here.
*/
def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] =
classTag[T].runtimeClass.asInstanceOf[jClass[T]]
The limitation is reminiscent of this question about pattern matching with `ClassTag`, in which our naive expectations are also not met.
Does the resistance to `Class[A]` represent the impedance mismatch between Scala types and the platform?
Given the class type, all one can really do is `newInstance`. But reflective invocation with a constructor mirror won't give me my type back.
scala> res24 reflectConstructor res25.asMethod
res27: reflect.runtime.universe.MethodMirror = constructor mirror for Bar.<init>(): Bar (bound to null)
scala> res27()
res28: Any = Bar@2eeb08d9
scala> bar.getClass.newInstance
res29: Bar = Bar@31512f0a
scala> classOf[Bar].newInstance
res30: Bar = Bar@2bc1d89f
That doesn't seem fair.
As that mailing thread from 2008 concludes, you expect to use fewer casts in Scala.
BTW, it's not that I disbelieved the code comment, but:
scala> 5.getClass
res38: Class[Int] = int
scala> :javap -
Size 1285 bytes
MD5 checksum a30a28543087238b563fb1983d7d139b
Compiled from "<console>"
[snip]
9: getstatic #27 // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
12: iconst_5
13: invokestatic #33 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
16: getstatic #38 // Field scala/reflect/ClassTag$.MODULE$:Lscala/reflect/ClassTag$;
19: invokevirtual #42 // Method scala/reflect/ClassTag$.Int:()Lscala/reflect/ClassTag;
22: invokevirtual #46 // Method scala/runtime/ScalaRunTime$.anyValClass:(Ljava/lang/Object;Lscala/reflect/ClassTag;)Ljava/lang/Class;
25: putfield #18 // Field res38:Ljava/lang/Class;
28: return
Problem
I'd like to have a method like ``` def retrieve[T](value: Option[T])(implicit ct: ClassTag[T]): T; ``` Inside this method I need to call a Java method (beyond my control) to create an instance of `T` that requires `Class[T]`: ``` public <T> T construct(clazz: Class<T> /* other arguments */) { ... } ``` How can I get `Class[T]` from `ClassTag[T]`? First I thought I could use `runtimeClass` from `ClassTag`, but it's type is `Class[_]`, not `Class[T]`. Or is there any other implicit value that compiler can automatically provide, from which I can obtain `Class[T]`?