适用于任何List和Generics / Type Erasure方面的方法

时间:2013-10-24 18:27:11

标签: java list generics type-erasure raw-types

首先创建一些代码(Java 7)来说明我的问题。

import java.util.*;

class Generics101 {



    public static void addTrue(List list) {
        list.add(true);
    }

    public static void main(String[] args) {
        List<Integer> testList = new ArrayList<>();

        addTrue(testList);
        System.out.println(testList.get(0));

        // testList.add(true);  // will not compile when uncommented

    }
}

我有以下两个问题:

  1. addTrue方法中,Eclipse提示它不喜欢raw types。当我尝试更改方法参数以使用通配符List<?> list时,它将无法编译。我查看Generics Tutorial但找不到答案。我在这里想念的是什么,我应该在哪里阅读它?

  2. 相同的tutorial声明“泛型被引入Java语言以在编译时提供更严格的类型检查... ”我理解由于{{1这样的强制执行不能在运行时发生,所以我的上面的代码编译并运行。如果注释行被取消注释,它将触发编译错误,因此我假设type erasure在同一方法中有效。这种执法的确切范围是什么?它是如何正式定义的?

1 个答案:

答案 0 :(得分:3)

  

当我尝试更改方法参数以使用通配符列表列表时,它将无法编译。

它无法编译,因为您无法在List<?>中添加任何内容。因为您不知道实际上会出现List的类型。例如,仅限您当前的案例。您正在通过List<Integer>。它将成功传递给List<?>。没有问题。但您要为其添加trueboolean类型。如果编译器允许,它将在运行时抛出ClassCastException。所以,这是不允许的。

  

因此我假设在同一方法中有更严格的类型检查。这种执法的确切范围是什么?

不,不是那样的。并不是类型检查是在某个范围内完成的。只要使用泛型,它就会被强制执行。如果与正确的泛型一起使用,您当前的代码将无法编译,因为您尝试将boolean类型添加到List<Integer>。你为什么期望这样做?

尝试将您的方法更改为通用方法,您将看到它无法编译:

public static <T> void addTrue(List<T> list) {
    list.add(true);  // Won't compile
}
  

我查看了Generics Tutorial但找不到答案。我在这里错过了什么,我应该在哪里阅读它?

嗯,这是Oracle的标准教程。这就是你应该阅读的地方。除此之外,您还可以在Java Generics FAQs - Angelika Langer.

上查看关于泛型的非常好的教程集