2017-07-19 87 views
5

我想了解泛型类型的用法,并且当我试验一些代码行时,我发现有些奇怪的东西。Java - 泛型类型和集合

的代码的第一部分是一个名为“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,真实,字符串]

这让我很困惑,因为arrInteger类型的ArrayList,怎么可以包含boolean类型和String的对象?是否将函数func中的列表转换为原始类型(这意味着它变为泛型类型Object)?如果是的话,怎么可能,因为你不能这样做,例如:List<Integer> arr = new ArrayList<Object>();

想了解一下这个,也许它会帮助我更好地掌握泛型类型的这个主题。谢谢!

+0

你应该阅读有关[RAW类型(https://docs.oracle.com/javase/tutorial/ java/generics/rawTypes.html)和[堆污染](https://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html#heap_pollution)。 – Flown

回答

1

Java不允许创建通用数组。 Java集合类主要使用Object数组实现。 ArrayList类可以看起来如下

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

在创建ArrayListObject[]阵列创建能够容纳任何类型的对象的新实例。 Typesafety只能通过使用泛型类型参数来实现。

因为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

这类输出的背后原因是要传递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"); 
     } 
1

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

当我们打电话给System.out.println(arr.toString())时,我们只是在打印一个对象。这将罚款任何类型(即,int,布尔值,字符串等)。这就是为什么我们没有遇到任何异常。

然而,仅仅尝试分配从这个列表中的值,我们将java.lang.ClassCastException

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