Scala classOf用于类型参数


79

我正在尝试使用scala / java创建用于对象更新的通用方法,但无法获取类型参数的类。

这是我的代码:

object WorkUnitController extends Controller {     
 def updateObject[T](toUpdate: T, body: JsonObject){
  val source = gson.fromJson(body, classOf[T]);
  ...
 }
}

我得到的错误是

类别类型为必填项,但找到了T

我知道在Java中您无法做到这一点,但是在Scala中这是否可能呢?

谢谢!


Answers:


92

由于清单弃用(因为斯卡拉2.10.0),这是更新的答案-

import scala.reflect.ClassTag
import scala.reflect._

object WorkUnitController extends Controller {
  def updateObject[T: ClassTag](toUpdate: T, body: JsonObject){
    val source = gson.fromJson(body, classTag[T].runtimeClass)
    ???
  }
}

您应该使用ClassTag代替ClassManifest.runtimeClass代替.erasure

原始答案- 是的,您可以使用清单来做到这一点:

object WorkUnitController extends Controller {     
 def updateObject[T: ClassManifest](toUpdate: T, body: JsonObject){
  val source = gson.fromJson(body, classManifest[T].erasure);
  ...
 }
}

哦,天哪,太神奇了!我希望我早些知道!
Darkzaelus 2011年

1
您甚至可以写manifest[T]而不是implicitly[Manifest[T]]
Jean-Philippe Pellet

1
@ mericano1已经成为该语言的重要组成部分,我认为清单不再是一种实验性功能
Vasil Remeniuk 2011年

12
@ mericano1一个更新:ManifestClassManifest,现在已弃用,在Scala 2.10上分别被TypeTag和取代ClassTag
Daniel C. Sobral 2012年

9
而不是classTag[T].runtimeClass我需要的classTag[T].runtimeClass.asInstanceOf[Class[T]]。有人知道为什么吗?
kosii 2014年

6

Vasil和Maxim的回答对我有所帮助。

就我个人而言,我更喜欢在其中implicit添加此类参数的语法(本文提供: ClassTag的缩写形式。因此,在此情况下,以防其他人也认为这是一种更好的方法:

import scala.reflect.ClassTag

object WorkUnitController extends Controller {
  def updateObject[T](toUpdate: T, body: JsonObject)(implicit tag: ClassTag[T]){
    val source = gson.fromJson(body, tag.runtimeClass)
    ???
  }
}

免责声明:我没有编译上面的内容,但是我自己的类似代码以这种方式工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.