Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala classOf for type parameter

Tags:

scala

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!

like image 993
mericano1 Avatar asked Jun 01 '11 11:06

mericano1


People also ask

What is a type parameter Scala?

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.

What is classOf in Scala?

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]

How do I use generics in Scala?

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.

Does Scala support generics?

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, [ ].


2 Answers

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);   ...  } } 
like image 196
Vasil Remeniuk Avatar answered Sep 21 '22 00:09

Vasil Remeniuk


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.

like image 20
akauppi Avatar answered Sep 21 '22 00:09

akauppi