0

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!

Community
  • 1
  • 1
Alex Dean
  • 15,575
  • 13
  • 63
  • 74
  • To call it, just pass an argument to `get` the type will be inferred. – paradigmatic Aug 02 '11 at 08:03
  • 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 02 '11 at 08:19

3 Answers3

5

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.

paradigmatic
  • 40,153
  • 18
  • 88
  • 147
  • Big thanks paradigmatic, that worked great. I found a great explanation of implicit parameters here: http://stackoverflow.com/questions/3855595/scala-function-implicitly – Alex Dean Aug 02 '11 at 08:45
3

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.

Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
1

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
Paolo Falabella
  • 24,914
  • 3
  • 72
  • 86
  • 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 02 '11 at 08:20