1

I would like to know the name of a generic class.

The solution I use now is the following one. I defined the class class A[T: ClassTag] {...} to be able to do classTag[T].toString.

This compiles, but there is a problem with Guice. I get the error No implementation for scala.reflect.ClassTag<com.test.Person> was bound.

Is there :

  • Another solution to know the name of a generic class that could work with Guice ? or
  • A way to bind ClassTag[T] with Guice ?

Full code :

package com.test

case class Person(age: Int)

class A[T: ClassTag] {

  // I need to know the (full) name of type T (e.g. com.test.Person)
  val tClassName = classTag[T].toString

}

class B @Inject()(a: A[Person]) {

}
Dnomyar
  • 707
  • 5
  • 17
  • Perhaps you can use Guice's `TypeLiteral` instead of `ClassTag`? – Tavian Barnes Sep 06 '16 at 16:07
  • I have found some topics to use `TypeLiteral` http://stackoverflow.com/questions/8772555/generics-hell-can-i-construct-a-typeliteralsett-using-generics https://groups.google.com/forum/#!topic/google-guice/1jbWcdeCF6U . I tried to implement that in Scala with Guice but I didn't succed. Ex : `@Provides def provideTest[T: ClassTag](): TypeLiteral[ClassTag[T]] = { TypeLiteral.get(Types.newParameterizedType(ClassTag.getClass, classTag[T].getClass)) }` (does not compile). Any idea ? – Dnomyar Sep 07 '16 at 13:14
  • Not sure what you're doing there, but I really did mean *instead of* `ClassTag`. – Tavian Barnes Sep 07 '16 at 13:20
  • I do not see what you mean. Could you give me an exemple please. – Dnomyar Sep 08 '16 at 16:37
  • From a `TypeLiteral`, you can use `typeLiteral.getType().getTypeName()` to get the full name of `Person`. I don't know Scala so I can't really give a Scala example. But the issue is that `ClassTag` isn't injectable, while `TypeLiteral` is. – Tavian Barnes Sep 08 '16 at 17:00
  • Thanks a lot, its works ! – Dnomyar Sep 09 '16 at 10:00

1 Answers1

0

Thanks to @tavian-barnes help, I found the way to solve this problem. The solution is to add to A an implicit value TypeLiteral[T]. Then, you just have to call typeLiteral.getType.getTypeName to get the full name of geneirc class T.

Full code :

package com.test

case class Person(age: Int)

class A[T]()(implicit val typeLiteral: TypeLiteral[T]) {

  val tClassName = typeLiteral.getType.getTypeName

}

class B @Inject()(a: A[Person]) {

    println(a.tClassName) // prints `com.test.Person`

}
Dnomyar
  • 707
  • 5
  • 17