Estoy tratando de crear un método genérico para actualizaciones de objetos usando scala / java pero no puedo obtener la clase para un parámetro de tipo.
Aquí está mi código:
object WorkUnitController extends Controller {
def updateObject[T](toUpdate: T, body: JsonObject){
val source = gson.fromJson(body, classOf[T]);
...
}
}
El error que obtengo es
tipo de clase requerido pero T encontrado
Sé que en Java no puedes hacerlo, pero ¿es esto posible en Scala?
¡Gracias!
Respuestas:
Due Manifest está en desuso (desde Scala 2.10.0) esta es la respuesta actualizada:
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) ??? } }
Deberías usar en
ClassTag
lugar deClassManifest
y en.runtimeClass
lugar de.erasure
Respuesta original: sí, puede hacerlo usando manifiestos:
object WorkUnitController extends Controller { def updateObject[T: ClassManifest](toUpdate: T, body: JsonObject){ val source = gson.fromJson(body, classManifest[T].erasure); ... } }
fuente
manifest[T]
lugar deimplicitly[Manifest[T]]
.Manifest
yClassManifest
ahora están en desuso, habiendo sido reemplazados conTypeTag
yClassTag
, respectivamente, en Scala 2.10.classTag[T].runtimeClass
que necesitabaclassTag[T].runtimeClass.asInstanceOf[Class[T]]
. ¿Alguien sabe por qué?La respuesta de Vasil y Maxim me ayudó.
Personalmente, prefiero la sintaxis donde
implicit
se usa para agregar tales parámetros (la que se presenta: ClassTag
es una abreviatura para ello. Así que aquí, en caso de que alguien más también vea que esta es una mejor manera: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) ??? } }
Descargo de responsabilidad: no compilé lo anterior, pero mi propio código similar funciona de esta manera.
fuente