我想要一个像
这样的方法def retrieve[T](value: Option[T])(implicit ct: ClassTag[T]): T;
在这个方法中,我需要调用一个Java方法(超出我的控制范围)来创建一个需要T
的{{1}}实例:
Class[T]
如何从public <T> T construct(clazz: Class<T> /* other arguments */) { ... }
获取Class[T]
?首先我想我可以使用ClassTag[T]
中的runtimeClass
,但它的类型是ClassTag
,而不是Class[_]
。或者是否有编译器可以自动提供的任何其他隐式值,我可以从中获取Class[T]
?
答案 0 :(得分:14)
getClass
上的{p> 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 matching与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
这似乎不公平。
从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