TypeTag
еще не обновлено для Manifest
, потому что это часть экспериментального и нестабильного отражения Scala. На данный момент вы определенно не должны использовать его для производства.
Для случая использования вы показали, где нужен только класс выполнения (не полный тип информации с дженериков и т.д.), Scala 2.10 введенными ClassTag
, которые вы можете использовать, как это:
def newInstance[T: ClassTag] =
implicitly[ClassTag[T]].runtimeClass.newInstance.asInstanceOf[T]
или:
def newInstance[T](implicit ct: ClassTag[T]) =
ct.runtimeClass.newInstance.asInstanceOf[T]
В любом случае, Manifest
еще не устарели, поэтому, я думаю, вы все равно можете его использовать.
EDIT:
Использование TypeTag
для достижения того же:
import scala.reflect.runtime.universe._
def newInstance[T: TypeTag] = {
val clazz = typeTag[T].mirror.runtimeClass(typeOf[T])
clazz.newInstance.asInstanceOf[T]
}
выше решение до сих пор использует некоторые Java отражение. Если мы хотим быть пуристическими и использовать только Scala отражение, это решение:
def newInstance[T: TypeTag]: T = {
val tpe = typeOf[T]
def fail = throw new IllegalArgumentException(s"Cannot instantiate $tpe")
val noArgConstructor = tpe.member(nme.CONSTRUCTOR) match {
case symbol: TermSymbol =>
symbol.alternatives.collectFirst {
case constr: MethodSymbol if constr.paramss == Nil || constr.paramss == List(Nil) => constr
} getOrElse fail
case NoSymbol => fail
}
val classMirror = typeTag[T].mirror.reflectClass(tpe.typeSymbol.asClass)
classMirror.reflectConstructor(noArgConstructor).apply().asInstanceOf[T]
}
Благодаря @ghik, я все еще был бы интересно узнать, как сделать это с TypeTag, предпочтительно при сохранении полной информации о типе, то есть умозаключение тип должен вывести 'newInstance [MyClass {Int]]: MyClass [Int] ' –
@ DanielMahler Я добавил решение типа TypeTag. См. Мое редактирование. – ghik
@ghik, когда вы используете 'runtimeMirror (this.getClass.getClassLoader)' вы можете получить исключение, если 'T' не загружается с тем же загрузчиком классов, что и' this.type'. Вы должны использовать зеркало, прикрепленное к 'TypeTag':' typeTag [T] .mirror'. –