【问题标题】:Scala classOf for type parameterScala classOf 用于类型参数
【发布时间】:2011-09-06 05:08:18
【问题描述】:

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

这是我的代码:

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

我得到的错误是

需要类类型,但找到了 T

我知道在 java 中你不能这样做,但在 scala 中这可能吗?

谢谢!

【问题讨论】:

标签: scala


【解决方案1】:

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)
    ???
  }
}

免责声明:我没有编译上面的代码,但我自己的类似代码是这样工作的。

【讨论】:

    【解决方案2】:

    由于 Manifest弃用(自 Scala 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);
      ...
     }
    }
    

    【讨论】:

    • 天哪,太神奇了!我希望我早点知道这件事!
    • 你甚至可以写manifest[T]而不是implicitly[Manifest[T]]
    • @mericano1 它们已成为该语言的重要组成部分,而且我认为,Manifests 不再是实验性功能
    • @mericano1 一个更新:ManifestClassManifest 现在已弃用,在 Scala 2.10 上已分别替换为 TypeTagClassTag
    • 我需要classTag[T].runtimeClass.asInstanceOf[Class[T]] 而不是classTag[T].runtimeClass。有人知道为什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多