我想有一个像

def retrieve[T](value: Option[T])(implicit ct: ClassTag[T]): T;

在此方法内部,我需要调用Java方法(在控件之外)来创建需要TClass[T]实例:

public <T> T construct(clazz: Class<T> /* other arguments */) { ... }

如何从Class[T]获取ClassTag[T]?首先我以为我可以使用runtimeClass中的ClassTag,但是它的类型是Class[_],而不是Class[T]。还是编译器可以自动提供其他隐式值,我可以从中获取Class[T]

最佳答案

getClass上的Here is the ticket和Odersky在其中推测的linked forum discussion:



Here is the duplicate ticket,其中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]]

局限性使人联想到this question about pattern matchingClassTag,其中也没有满足我们的幼​​稚期望。
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

那似乎不公平。

随着2008年该邮件线程的结束,您希望在Scala中使用较少的强制类型转换。

顺便说一句,不是我不相信代码注释,而是:
scala> 5.getClass
res38: Class[Int] = int

scala> :javap -
  Size 1285 bytes
  MD5 checksum a30a28543087238b563fb1983d7d139b
  Compiled from "<console>"

[片段]
 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

10-03 00:37