如何从隐式ClassTag [T]中获取Class [T]?

Pet*_*lák 12 reflection scala class scala-2.10

我想要一个像这样的方法

def retrieve[T](value: Option[T])(implicit ct: ClassTag[T]): T;
Run Code Online (Sandbox Code Playgroud)

在这个方法中,我需要调用一个Java方法(超出我的控制范围)来创建一个T需要的实例Class[T]:

public <T> T construct(clazz: Class<T> /* other arguments */) { ... }
Run Code Online (Sandbox Code Playgroud)

我怎样才能Class[T]ClassTag[T]?首先,我想我可以用runtimeClassClassTag,但它的类型Class[_],不是Class[T].或者是否有编译器可以自动提供的其他隐式值,我可以从中获取Class[T]

som*_*ytt 14

这是门票getClass链接的论坛讨论中Odersky的推测:

你也可以使用演员表.

这里是重复的票哪里getClass是固定的.5.getClass还演员:

/** 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]]
Run Code Online (Sandbox Code Playgroud)

该限制是让人联想到的关于这个模式匹配问题ClassTag,在我们的天真的期望也没有得到满足.

阻力是否Class[A]代表Scala类型与平台之间的阻抗不匹配?

鉴于类类型,所有人都可以做到newInstance.但是使用构造函数镜像的反射调用不会给我回复类型.

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
Run Code Online (Sandbox Code Playgroud)

这似乎不公平.

从2008年的邮件线程结束时,您希望在Scala中使用更少的强制转换.

顺便说一句,并不是我不相信代码评论,而是:

scala> 5.getClass
res38: Class[Int] = int

scala> :javap -
  Size 1285 bytes
  MD5 checksum a30a28543087238b563fb1983d7d139b
  Compiled from "<console>"
Run Code Online (Sandbox Code Playgroud)

[剪断]

 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        
Run Code Online (Sandbox Code Playgroud)