简体   繁体   中英

Scala trait runtime class from type parameter

I have a scala trait [this trait does not compile]

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

And a Java class

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? What I'm currently doing is adding a Class[T] field like this

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.

Nice and common way of working around type erasure in Scala is to use ClassTag s. They're usually passed as implicit parameters. Unfortunately, traits can't take constructor parameters, so the best that we can have is:

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:

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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