Java - 通用类型和集合

时间:2017-07-19 08:55:54

标签: java collections generic-collections

我正在尝试学习泛型类型的使用,当我尝试使用某些代码时,我注意到了一些奇怪的东西。

第一段代码位于名为“A”的类中:

public void func(int k, List list) {
    list.add(9);
    list.add(true);
    list.add("a string");
    }

第二段代码位于主函数内的不同类中:

List<Integer> arr = new ArrayList<Integer>();
        arr.add(14);
        System.out.println(arr.toString());
        a.func(8, arr);
        System.out.println(arr.toString());

运行代码导致打印这行:

  

[14]

     

[14,9,true,a string]

由于arr是类型为ArrayList的{​​{1}},这让我非常困惑,它如何包含Integerboolean类型的对象?是否将函数String中的列表转换为原始类型(这意味着它变为泛型类型func)?如果是这样,怎么可能,因为你不能这样做,例如:Object

希望对此有所澄清,也许它会帮助我更好地掌握这类泛型类型的主题。谢谢!

3 个答案:

答案 0 :(得分:1)

Java不允许创建通用数组。 Java Collection Classes主要使用Object数组实现。 ArrayList类可能如下所示

public class ArrayList<T> implements List<T>, Serializable {
    private transient Object[] data;
    // more content...
}

创建ArrayList的新实例时,会创建一个可以容纳任何类型对象的新Object[]数组。只能通过使用通用类型参数来实现类型安全。

由于List没有提供任何Type参数,因此它使用了rawtype,并且可以将任何内容添加到列表中。因此,请始终确保推断模板参数以保持类型安全。

public void func(int k, List<Integer> list) {
    list.add(9);      // works
    list.add(true);   // compile error
    list.add("a string");  // compile error
}

你永远不应该使用rawtypes。根据您的编译器设置,将省略警告。 使用(绑定/未绑定)通配符更好。

答案 1 :(得分:1)

此类输出背后的原因是您将List作为参数传递给func( int k , List list ) . func 方法中的列表是非通用的,它允许您添加字符串,以便获得此类输出。

 List<Integer> arr = new ArrayList<Integer>();
                arr.add(14);
                System.out.println(arr.toString());
                a.func(8, arr); // here you are passing a list 
                System.out.println(arr.toString());

    public void func(List list) { // here List in non-generic 
        list.add(9);
        list.add(true);
        list.add("a string");
        }

答案 2 :(得分:1)

Java中的通用代码的重点是在实际代码编译之前提供类型安全性。编译后的代码没有类型,这就是为什么我们在代码中没有遇到任何问题,因为在调用实际的func()方法时,List arr没有任何问题类型。

当我们拨打System.out.println(arr.toString())时,我们只是打印一个对象。这将适用于任何类型(即int,boolean,String等...)。这就是为什么我们不会遇到任何例外。

但是,只需尝试从此列表中指定一个值,我们就会获得java.lang.ClassCastException

...
func(8, arr);
System.out.println(arr.toString());
int a = arr.get(2);