I am trying to create a generic method for object updates using scala / java but I can't get the class for a type parameter.
Here is my code:
object WorkUnitController extends Controller { def updateObject[T](toUpdate: T, body: JsonObject){ val source = gson.fromJson(body, classOf[T]); ... } }
The error i get is
class type required but T found
I know in java you can't do it but is this possible in scala at all?
Thanks!
Language. Methods in Scala can be parameterized by type as well as by value. The syntax is similar to that of generic classes. Type parameters are enclosed in square brackets, while value parameters are enclosed in parentheses.
A classOf[T] is a value of type Class[T] . In other words, classOf[T]: Class[T] . For example: scala> val strClass = classOf[String] strClass: Class[String] = class java. lang. String scala> :t strClass Class[String]
To use a generic class, put the type in the square brackets in place of A . The instance stack can only take Ints. However, if the type argument had subtypes, those could be passed in: Scala 2.
The classes that takes a type just like a parameter are known to be Generic Classes in Scala. This classes takes a type like a parameter inside the square brackets i.e, [ ].
Due Manifest is deprecated (Since Scala 2.10.0) this is the updated answer -
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) ??? } }
You should use ClassTag
instead of ClassManifest
and .runtimeClass
instead of .erasure
Original answer - Yes, you can do that using manifests:
object WorkUnitController extends Controller { def updateObject[T: ClassManifest](toUpdate: T, body: JsonObject){ val source = gson.fromJson(body, classManifest[T].erasure); ... } }
Vasil's and Maxim's answer helped me.
Personally, I prefer the syntax where implicit
is used for adding such parameters (the presented : ClassTag
is shorthand for it. So here, in case someone else also sees this to be a better way:
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) ??? } }
Disclaimer: I did not compile the above, but my own similar code works this way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With