简体   繁体   English

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

[英]Scala trait runtime class from type parameter

I have a scala trait [this trait does not compile] 我有一个scala特征[这个特性不能编译]

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

And a Java class 还有一个Java类

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

How can I make the trait valid scala? 如何使特征有效scala? What I'm currently doing is adding a Class[T] field like this 我目前正在做的是添加像这样的Class[T]字段

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

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

but I don't like having to add a t field to all classes that want to use this trait. 但是我不想在所有想要使用这个特性的类中添加一个t字段。

Nice and common way of working around type erasure in Scala is to use ClassTag s. 在Scala中解决类型擦除的常见方法是使用ClassTag They're usually passed as implicit parameters. 它们通常作为隐式参数传递。 Unfortunately, traits can't take constructor parameters, so the best that we can have is: 不幸的是,traits不能采用构造函数参数,所以我们可以拥有的最好的是:

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

Then, every class extending MyTrait must be defined like this: 然后,每个扩展MyTraitMyTrait必须这样定义:

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

Then, if you have some concrete enum MyEnum , you can create instances of your class seamlessly: 然后,如果你有一个具体的枚举MyEnum ,你可以无缝地创建你的类的实例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM