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

 

posted @ 2016-04-15 05:58  新一代的天皇巨星  阅读(315)  评论(0编辑  收藏  举报