使用泛型转换数组

时间:2013-08-24 16:42:51

标签: java arrays generics

以下陈述之间有什么区别:

List<E>[] x = (List<E>[]) new List[100];

List<E>[] x = new List[100];

在我的脚本中,注意前者是创建泛型数组的正确方法(尽管它会导致编译器警告)。但我无法弄清楚(List<E>[])语句的用法是什么。 List<E>[]甚至不是它自己的类型,编译器只会用(List[])替换它,所以你得到

List<E>[] x = (List[]) new List[100];

List[]转换为List[],这是无用的。那么为什么首先放入(List<E>[])呢?

3 个答案:

答案 0 :(得分:3)

  

泛型通过在编译时检测到更多错误来增加代码的稳定性。

这是我给出的链接的一部分,认为同样重要,所以我在这里张贴

  

这是接口 List的定义的一小段摘录   和java.util包中的Iterator

public interface List <E> {
    void add(E x);
    Iterator<E> iterator();
}

public interface Iterator<E> {
    E next();
    boolean hasNext();
}
     

这个代码应该都很熟悉,除了角度的东西   括号。这些是接口List和Iterator的formal type parameters的声明。

     

类型参数可以在整个通用声明中使用,非常好   你会使用普通类型的地方。

     

我们知道泛型类型声明List的调用,例如    的列表。在调用中(通常称为参数化    输入),所有出现的形式类型参数(在本例中为E)    将替换为实际的类型参数(在本例中为Integer)。

     
    

您可能会想到List代表List的版本     其中E已被Integer统一替换:

  
public interface IntegerList {
        void add(Integer x);
        Iterator<Integer> iterator();
    }
     

这种直觉可能有所帮助,但它也误导

     

这很有用,因为参数化类型List有   确实有一些方法看起来就像这种扩张。

     

这是误导性的,因为通用的声明永远不会   实际上以这种方式扩展。没有多个副本   代码 - 不是源代码,不是二进制代码,不是磁盘而不是内存。

     
    

泛型类型声明一劳永逸地编译并转换     单个类文件,就像普通的类或接口一样     声明。

         

类型参数类似于中使用的普通参数     方法或构造函数。很像一种方法具有正式价值     用于描述其操作的值类型的参数,通用的     声明具有正式的类型参数。调用方法时     实际参数代替形式参数,以及     方法体被评估。

  
     

当调用泛型声明时,   实际类型参数替换形式类型参数。这就是泛型的重要性。

     

您可以在此处查看more information about Generics

答案 1 :(得分:1)

此:

List<E>[] x = new List[100];

表示x是一种数组类型。该数组的元素是列表,可以容纳类型E 对象。并且您正在为其分配一系列列表,这些列表可以容纳任何对象

下一个声明:

List<E>[] x = (List<E>[]) new List[100];

不是更好。施法无济于事。这个缺陷仍然是一样的。

最终,所有这些都是这样做的借口:

List<E>[] x =  new List<E>[100];

Java中不允许使用泛型数组。因为Arrays在运行时保持它们的元素类型,而泛型构造则不然。必须没有没有严格定义元素类型的数组。

问题是由于定义了一个引用类型List<E>[],根据定义,它不允许在Java中实例化。所以,避免使用这种类型。

您可以使用列表列表作为替代。

答案 2 :(得分:1)

与泛型一样,存储在任何集合中的对象类型将在添加到集合中时进行类型检查。主要通过泛型,其他那些不需要了解泛型的人可以理解代码。因此,通过在编译时插入检查并在运行时擦除可以实现此行为。

你可以看到:http://docs.oracle.com/javase/tutorial/java/generics/