3

I have the following Java method:

public <T> void foo(Class<T> parentClass, Class<? extends T> childClass);

I tried to use an implicit ClassTag to call the above method, but unfortunately the runtime methods returns an erased class, i.e., Class[_], which means the follow code won't work:

import scala.reflect.classTag
def bar[A: ClassTag, B <: A : ClassTag] = foo(classTag[A].runtimeClass, classTag[B].runtimeclass)

I can get around it by using asInstanceOf, but I was wondering if there's a cleaner solution. It feels really weird to me that there isn't a method that returns a non-erased Class value from a ClassTag in the standard library.

To be clear, I'm looking for an existing method (In the ClassTag class or elsewhere) with the following signature:

def unerasedRuntimeClass[A: ClassTag]: Class[A] = ???

Gal
  • 5,338
  • 5
  • 33
  • 55
  • 1
    For what it's worth, this is basically the same question as [this one](https://stackoverflow.com/questions/23974706/how-do-i-get-the-classof-a-classtag), for which the only answer is to use `asInstanceOf`. As to why `runtimeClass` returns an existential type, I do not understand. – Owen Sep 03 '18 at 03:43
  • Also, just a note on terminology, it's not really an "erased" type; all Scala types are erased. It's an existential type, meaning that it's not providing any guarantees as to what the type parameter is. I guess what this means is that the author of `runtimeClass` must have thought that it's possible that there is some `T` for which `classTag[T].runtimeClass.newInstance()` would yield a non-`T`. I can't think of what that would be, though. – Owen Sep 03 '18 at 03:58
  • @Owen I'm using the terminology scala uses, e.g., "A ClassTag[T] stores the erased class of a given type T" (https://www.scala-lang.org/api/2.12.3/scala/reflect/ClassTag.html). – Gal Sep 03 '18 at 09:00
  • I think that's referring to the runtime information stored by `ClassTag`—that is, a `ClassTag[List[Int]]` stores information about `List` but not about `Int`. Note that even if the runtime information has nothing about `Int`, the static type can still be `ClassTag[List[Int]]`. – Owen Sep 03 '18 at 10:32

0 Answers0