ximyu
ximyu

Reputation: 2639

How to get the actual type of primitive type parameter in Scala Seq[T] or Option[T]?

For example if I have a class NewClass(val a: Seq[String]), I'm able to get the actual type of the type parameter by classOf[NewClass].getDeclaredFields.head.getGenericType.asInstanceOf[java.lang.reflect.ParameterizedType].getActualTypeArguments.head.asInstanceOf[Class[_]] which is a java.lang.String.

However, if the type parameter is a primitive type (which is not allowed in Java, but allowed in Scala), such as class NewClass(val a: Seq[Int]), using the same approach would only yield java.lang.Object. Is there any way for me to know that it's actually an Int instead of the general java.lang.Object?

Upvotes: 0

Views: 427

Answers (2)

Ivan Meredith
Ivan Meredith

Reputation: 2222

If you define a version like below it will work for all classes that have one type parameter.

scala> def f[F[_],A](a: F[A])(implicit m:Manifest[A]) = m.erasure
f: [F[_], A](a: F[A])(implicit m: Manifest[A])java.lang.Class[_]

scala> f(Option(1))
res4: java.lang.Class[_] = int

scala> f(List(1,2,3))
res5: java.lang.Class[_] = int

scala> f(new NewClass(Seq(1, 2, 3)))
res6: java.lang.Class[_] = int

scala> f(new NewClass(Seq(1, 2, 3)).a)
res8: java.lang.Class[_] = int

Upvotes: 0

drstevens
drstevens

Reputation: 2913

Can you use the manifest?

scala> class NewClass[T](val a: Seq[T])(implicit m: Manifest[T])
defined class NewClass

scala> class NewClass[T](val a: Seq[T])(implicit m: Manifest[T]) {
     |   def typeOfA = m.erasure
     | }
defined class NewClass

scala> val newClass = new NewClass(Seq(1, 2, 3))
newClass: NewClass[Int] = NewClass@494e1df7

scala> newClass.typeOfA
res17: java.lang.Class[_] = int

Upvotes: 2

Related Questions