来自类型参数的Scala trait运行时类

时间:2014-02-13 20:16:40

标签: scala type-parameter

我有一个scala特征[此特征无法编译]

trait MyTrait[T <: Enum] {
  def myMethod(name: String): T = {
    MyJavaClass.staticMethod(name, classOf[T])
  }
}

和Java类

public class MyJavaClass {
    public static <T extends Enum> T staticMethod(String name, Class<T> c) {
        return (T) T.valueOf(c, name);
    }
}

如何使特征有效scala?我目前正在做的是添加像这样的Class[T]字段

trait MyTrait[T <: Enum] {
  val t: Class[T]

  def myMethod(name: String): T = {
    MyJavaClass.staticMethod(name, t)
  }
}

但我不想在所有想要使用此特征的类中添加t字段。

1 个答案:

答案 0 :(得分:9)

在Scala中解决类型擦除的常见方法是使用ClassTag s。 它们通常作为隐式参数传递。遗憾的是,特征不能采用构造函数参数,因此我们可以拥有的最好的是:

import scala.reflect.ClassTag

trait MyTrait[T <: Enum] {
  val ttag: ClassTag[T]

  def myMethod(name: String): T = {
    MyJavaClass.staticMethod(name, ttag.runtimeClass.asInstanceOf[Class[T]])
  }
}

然后,每个扩展MyTrait的类都必须这样定义:

class MyClass[T <: Enum](/*your params, if any*/)(implicit val ttag: ClassTag[T]) extends MyTrait[T] {
  /*your class body*/
}

然后,如果你有一个具体的枚举MyEnum,你可以无缝地创建你的类的实例:

new MyClass[MyEnum](/*your params, if any*/)