scala 与 java泛型数组

java 泛型数组初始化

public class GenericArray<T> {

    private T[] arr;

    public GenericArray(){
        arr = new T[10]; //编译错误
    }

}

使用这样的方式初始化java的数组会出错,因为java不支持泛型数组。按照我的理解,java 初始化数组时候,需要知道数组的确切类型,但是泛型是编译后擦除的。所以运行时,无法知道数组的确切类型。所以java不支持以 new T[] 方式初始化一个数组。

如果想进行初始化,可以通过这样的方式

T[] arr=(T[]) new Object[10];

scala的泛型数组

那么同样的场景,在scala中如何实现呢

class ScalaGenericArray[T]{
  val arr: Array[T] = new Array[T](10)
}

object ScalaGenericArray{
  def main(args: Array[String]): Unit = {
    val arr = new ScalaGenericArray[String]
  }
}

看起来很自然,但是在运行时候会报错:

Error:(9, 23) cannot find class tag for element type T
val arr: Array[T] = new Array[T](10)

原因和java的一样,虚拟机中,泛型相关的类型信息会被擦除,所以无法将T解释成实际类型String

那么如何做呢,此处我们需要将类型的信息以一个参数的方式传进去

class ScalaGenericArray[T](implicit classTag:ClassTag[T] ){ //让编译器帮我们传入类型信息

  val arr: Array[T] = new Array[T](10)

}

object ScalaGenericArray{
  def main(args: Array[String]): Unit = {
    val arr = new ScalaGenericArray[String]
  }
}
  1. 感觉这种方式有点类似于java为了获取一个泛型的信息,将类以参数的形式传入函数参数中
public <T> T test(Class<T> clazz) {
        System.out.println(clazz);
        //...
}
  1. 当然此处的ClassTag也可以使用Manifest,但是在scala 2.10.0后就不推荐使用了

  2. 这样写比较复杂,scala也提供另一种简单的方式,上下文界定

class ScalaGenericArray[T: ClassTag] {//此处不再需要提供参数
  val arr: Array[T] = new Array[T](10)
}

object ScalaGenericArray {
  def main(args: Array[String]): Unit = {
    val arr = new ScalaGenericArray[String]
  }
}

这是scala的语法糖,T:ClassTag 告诉scala存在一个类型为ClassTag[T] 的隐式参数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 泛型是Java 1.5引入的新特性。泛型的本质是参数化类型,这种参数类型可以用在类、变量、接口和方法的创建中,分别...
    何时不晚阅读 3,069评论 0 2
  • object 变量可指向任何类的实例,这让你能够创建可对任何数据类型进程处理的类。然而,这种方法存在几个严重的问题...
    CarlDonitz阅读 948评论 0 5
  • 本文大量参考Thinking in java(解析,填充)。 定义:多态算是一种泛化机制,解决了一部分可以应用于多...
    谷歌清洁工阅读 484评论 0 2
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,321评论 9 118
  • 有人说家是温暖的港湾……有人说家是磨难的起源 每个人对家的概念不一样 在我眼里~家就是碰到困难就可以躲避~别人都说...
    漂浮的孤舟阅读 439评论 0 0