Jay Taylor's notes

back to listing index

Scala classOf for type parameter: how to call the function and how to restrict with upper type bounds - Stack Overflow

[web search]
Original source (stackoverflow.com)
Tags: scala manifests classOf stackoverflow.com
Clipped on: 2012-09-25

I'm working with JAX-RS in Scala and trying to parameterise a call to:

val jc = JAXBContext.newInstance(classOf[MyClassName])

I've been using ClassManifests as per the answer here but have a couple of things I'm still struggling with. As background, my JAX-RS representations all extend a stubbed Representation class:

class Representation {}

class ExampleRepresentation extends Representation { ... }

So far I've defined my function using a ClassManifest like so:

def get[R: ClassManifest](representation: R): String = {
 
val jc = JAXBContext.newInstance(classManifest[R].erasure)
 
...
}

My first question is a bit of a silly one: how do I call this function? I can't figure out what to pass in to get() for the R type and the representation value (the accepted answer to the original question doesn't make this clear). I tried implicit typing as per paradigmatic's comment but the below generates a compile error:

get(PlatformRepresentation)

Compiling main sources...
  not found
: value PlatformRepresentation

My second question is: is it possible to apply an upper type bound on the R object? In other words, I know that:

R <: Representation

Is there a way of bounding this in get()'s ClassManifest type declaration?

Many thanks!

asked Aug 2 '11 at 7:47
Image (Asset 1/4) alt= 1,4351221

97% accept rate
  upvote
 flag
To call it, just pass an argument to get the type will be inferred. – paradigmatic Aug 2 '11 at 8:03
  upvote
 flag
Thanks paradigmatic - I have updated my question. I'm trying to clarify that I don't have a value to pass in to the get(), I only have a class name to pass in. – Alex Dean Aug 2 '11 at 8:19
add comment

3 Answers

up vote 4 down vote accepted

You need to suppress the argument if you don't have any:

def get[R <: Representation: ClassManifest]: String = {
   
val classManifest = implicitly[ClassManifest[R]] //to retrieve the class manifest
}

To call it:

get[PlatformRepresentation]

The type gets between square brackets.

answered Aug 2 '11 at 8:24
Image (Asset 2/4) alt= 12.3k31753
  upvote
 flag
Big thanks paradigmatic, that worked great. I found a great explanation of implicit parameters here: stackoverflow.com/questions/3855595/scala-function-implicitly – Alex Dean Aug 2 '11 at 8:45
add comment

About your second question: yes, there is a way to do that:

def get[R <: Representation: ClassManifest](representation: R): String

When you declare type parameters, you may include one lower bound with >:, one upper bound with <:, and as many context bounds (with :) and view bounds (with <%) that you need.

answered Aug 2 '11 at 8:01
Image (Asset 3/4) alt= 16.4k33180
add comment

an example:

scala> def b[T <: String : ClassManifest] (t:T) = t + " " + classManifest[T].era
sure
;
b
: [T <: String](t: T)(implicit evidence$1: ClassManifest[T])java.lang.String

scala
> b("hello")
res2
: java.lang.String = hello class java.lang.String

EDIT @paradigmatic is right, in your case it should be

scala> def c[T <: String : ClassManifest] = classManifest[T].erasure;
c
: [T <: String](implicit evidence$1: ClassManifest[T])java.lang.Class[_]

scala
> c[String];
res4
: java.lang.Class[_] = class java.lang.String
answered Aug 2 '11 at 8:16
Image (Asset 4/4) alt= 6,1051519
  upvote
 flag
Thanks paolo - but I don't have a value to pass in to b, I just have the class name. In other words, I need b(String) to work not b("string") (which of course it doesn't). – Alex Dean Aug 2 '11 at 8:20
add comment

Your Answer

 
community wiki

Not the answer you're looking for? Browse other questions tagged or ask your own question.