Parameterized Type
Type will be erased by compiler. So you cannot check against the parametized check as below.
Code:
import scala.util.Try trait A[T] class AInt extends A[Int] class ATryInt extends A[Try[Int]] object Test extends App { val a = new AInt() val aTryInt = new ATryInt() p(a) p(aTryInt) def p[T](a: A[T]) = a match { case a: A[Int] => println("Int" + a.getClass) case a: A[Try[Int]] => println("TryInt" + a.getClass) } }
Compiler warning message:
Warning:(21, 13) non-variable type argument Int in type pattern A[Int] is unchecked since it is eliminated by erasure case a: A[Int] => println("Int" + a.getClass) ^ Warning:(22, 13) non-variable type argument scala.util.Try[Int] in type pattern A[scala.util.Try[Int]] is unchecked since it is eliminated by erasure case a: A[Try[Int]] => println("TryInt" + a.getClass) ^
Output:
Intclass AInt
Intclass ATryInt
How to get the parameterized type at runtime? Use reflection. Scala provides ClassTag to keep the type information at compile time, and make it available at runtime.
import scala.reflect.ClassTag class A[T: ClassTag] { val t2 = implicitly[ClassTag[T]].runtimeClass val t = getType def getType(implicit cmpl: ClassTag[T]) = { cmpl.runtimeClass } } class AInt extends A[Int] class ADouble extends A[Double] object test extends App { val int = new AInt println(int.getType) println(int.t) println(int.t2) val double = new ADouble println(double.getType) println(double.t) println(double.t2) }
Output:
int
int
int
double
double
double