84

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!

2
  • See also: issues.scala-lang.org/browse/SI-5722 Commented Aug 15, 2013 at 15:34
  • You can simply do it in Java in this way: public <T> void updateObject(T toUpdate, JsonObject body) { gson.fromJson(body, toUpdate.getClass()); } Commented Jun 27, 2022 at 6:39

2 Answers 2

99

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); ... } } 
Sign up to request clarification or add additional context in comments.

16 Comments

You can even write manifest[T] instead of implicitly[Manifest[T]].
@mericano1 they've become an essential part of the language, and, I think, Manifests are no longer an experimental feature
@mericano1 One update: Manifest and ClassManifest are now deprecated, having been replaced with TypeTag and ClassTag, respectively, on Scala 2.10.
Instead of classTag[T].runtimeClass I needed classTag[T].runtimeClass.asInstanceOf[Class[T]]. Does anybody know why?
Would be interesting to get the answer. Basically what is the difference between Class[_] and Class[T] at run-time or compile time.
|
10

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) ??? } } 

Demonstration: https://scastie.scala-lang.org/Vij5rpHNRDCPPG1WHo566g

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.