ClassTag

scala中对泛型数组的支持,主要是利用隐式转换捕获泛型的类型,存储在manifest中

直接上代码

import scala.reflect.ClassTag

class Rdd[T: ClassTag] {


  def mkArray[T:ClassTag](elems: T*): Array[T] = {

    // 获取T的实际类型
        var clazz: ClassTag[T] = implicitly[ClassTag[T]]
        if (classOf[String] == clazz.runtimeClass) {
          print("RunTime Type T is java.lang.String")
        }
        if (classOf[Integer] == clazz.runtimeClass) {
          print("RunTime Type T is java.lang.Integer")
        }

        println(clazz)
    Array[T](elems: _*)
  }

  // 这个方法和上面那个方法实际上是一样的,而构建泛型数组是必须要这样一个显示的证明的,而对于普通的类泛型则不需要
  // ClassTag也能捕获运行时泛型的实例
  //  def mkArray[T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T]) = {
  //    var clazz: ClassTag[T] = implicitly[ClassTag[T]] //evidence
  //    if (classOf[String] == clazz.runtimeClass) {
  //      println("string")
  //    }
  //    print(evidence$1)
  //    Array[T](elems: _*)
  //  }

  def mkList[T](elems: T*) = {
    //    var clazz: ClassTag[T] = implicitly[ClassTag[T]] //evidence
    //    if (classOf[String] == clazz.runtimeClass) {
    //      println("string")
    //    }
    elems
  }

  def mkSet(elems: T*): Set[T] = {
    Set(elems: _*)
  }
}

object ClassTagApp extends App {

  private val stringRdd = new Rdd[String]
  private val stringArrz = stringRdd.mkArray("1", "2", "3")
  private val stringListz = stringRdd.mkList("1", "2", "3")
  private val stringSet = stringRdd.mkSet("1", "2", "3")


  private val intRdd = new Rdd[Int]

  private val intArrayz = intRdd.mkArray(1, 2, 3)
  private val intListz: Seq[Int] = intRdd.mkList(1, 2, 3)
  private val intSetz = intRdd.mkSet(1, 2, 3)
}
对于泛型数组而言,构建泛型数组一定需要Classtag

对于泛型而言,带上ClassTag也可以运行时捕捉一些运行信息,做一些额外的事


    var clazz: ClassTag[T] = implicitly[ClassTag[T]] //evidence
        if (classOf[String] == clazz.runtimeClass) {
          println("string")
        }

这段代码就是捕捉隐式转换的证据(显示) evidence,

可以根据evidence 判断当前的泛型式什么类



最后写一个java与scala对classTag的应用

java


public static <T> T  safe(T t,Class<T> clazz){
    try {
        return Optional.ofNullable(t).orElse(clazz.newInstance() );
    } catch (InstantiationException e) {
        e.printStackTrace();

    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return null;
}

scala

def safe[T](t:T)(implicit classTag: ClassTag[T]): T = {
  Optional.ofNullable(t).orElse(classTag.runtimeClass.newInstance().asInstanceOf[T])
}
 
String safe = Op.safe(null, ClassTag$.MODULE$.<String>apply(String.class));

 
var o=new Object
o=""

var str = Op.safe(o)
println(str)


对于java 版要获取泛型的一个实例,必须传入class的实例,对于scala变成,implicit class由编译器添加,java 如果要用的话就得手动添加classTag了



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值