原始类型和类型安全

时间:2016-06-14 22:48:15

标签: java generics type-conversion

所以,假设我有一个简单的列表,如果整数:

List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
// intList.add("zxc"); // this will obviously fail

现在让我们将列表包装在另一个列表中:

List<List<Integer>> listOfListOfInt = new ArrayList<>();
listOfListOfInt.add(intList);

一切都很好。现在让我们创建方法

private static void method1(List<? extends List> cont) { // [1]
    List<? super Date> data = cont.get(0);  // [2]
    data.add(new Date());
}

基本上我将DATE添加到列表中的第一个列表,因为我告诉它将该列表视为List<? super Date>。 它的工作原理是因为类型擦除,当然:

    method1(listOfListOfInt);
    System.out.println(intList);

打印[1, 2, Tue Jun 14 23:41:15 BST 2016],因此我的List<Integer>现在有一个日期。

现在我明白发生了什么,因为类型擦除List<? extends List>只是一个List,然后由我来决定放入什么,所以我把Date放了。

现在我不太明白的问题是为什么根本没有“未经检查的作业/通话”的警告?根据java编译器,代码是完全类型安全的吗?

如果在方法1中您将List<? extends List>替换为List<List>,或者如果您仅用{{1}替换List<? super Date>,则会发出警告等等,一般情况下,您会收到有关未经检查的分配/调用的警告。但在这种情况下你不会,一切都很好。

更新:显然编译器会发出警告,但Intellij Idea由于某种原因拒绝显示它。我有“未经检查的警告”检查设置而不忽略任何东西。无论如何,所有设置都是默认设置。

  

IntelliJ IDEA 2016.1.3 Build#IC-145.1617,建于2016年6月3日JRE:   1.8.0_77-b03 x86 JVM:Oracle Corporation的Java HotSpot(TM)服务器VM

Update2:它不是重复的,因为问题不是关于原始类型的功能,而是关于在这种特殊情况下缺少警告。事实证明这只是一个IDE的怪癖。

1 个答案:

答案 0 :(得分:1)

您的问题是在此声明中使用原始类型:List<? extends List>。第二个List raw 。您的问题与类型擦除无关

在Eclipse中输入以下代码时,会收到警告。

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);
        List<List<Integer>> listOfListOfInt = new ArrayList<>();
        listOfListOfInt.add(intList);
        method1(listOfListOfInt);
        System.out.println(listOfListOfInt);
    }
    private static void method1(List<? extends List> cont) { // [1]
        List<? super Date> data = cont.get(0);  // [2]
        data.add(new Date());
    }
}

Eclipse的警告

[1] List is a raw type. References to generic type List<E> should be parameterized
[2] Type safety: The expression of type capture#1-of ? extends List needs unchecked conversion to conform to List<? super Date>

使用jdk1.8.0_91进行编译时,我得到:

Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

添加-Xlint:unchecked,我得到:

Test.java:17: warning: [unchecked] unchecked conversion
                List<? super Date> data = cont.get(0);  // [2]
                                                  ^
  required: List<? super Date>
  found:    CAP#1
  where CAP#1 is a fresh type-variable:
    CAP#1 extends List from capture of ? extends List
1 warning

正如您所看到的,您已被警告,无论是IDE(我的情况下是Eclipse)还是Java编译器。