Я пытаюсь создать универсальный метод для обновления объектов с помощью scala / java, но не могу получить класс для параметра типа.
Вот мой код:
object WorkUnitController extends Controller {
def updateObject[T](toUpdate: T, body: JsonObject){
val source = gson.fromJson(body, classOf[T]);
...
}
}
Я получаю ошибку
тип класса требуется, но найдено T
Я знаю, что в java это невозможно, но возможно ли это вообще в Scala?
Благодаря!
Ответы:
Из манифеста является устаревшим (Поскольку 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]]
.Manifest
иClassManifest
теперь устарели, будучи заменены наTypeTag
иClassTag
, соответственно, в Scala 2.10.classTag[T].runtimeClass
мне было нужноclassTag[T].runtimeClass.asInstanceOf[Class[T]]
. Кто-нибудь знает почему?Мне помог ответ Василия и Максима.
Лично я предпочитаю синтаксис, в котором
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) ??? } }
Отказ от ответственности: я не компилировал вышеупомянутое, но мой собственный аналогичный код работает таким образом.
источник