0

首先是为了说明我的问题而创建的一些代码(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时,它不会编译。我浏览了泛型教程,但找不到答案。我在这里缺少什么,我应该在哪里阅读它?

  2. 同一个教程指出“ Java 语言中引入了泛型以在编译时提供更严格的类型检查...... ”我知道由于type erasure这种强制措施不能在运行时发生,所以我上面的代码编译并运行。如果注释行未注释,它将触发编译错误,因此我假设tighter type checks在同一方法中有效。这种执法的确切范围是什么?它是如何正式定义的?

4

1 回答 1

3

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

它不会编译,因为你不能在List<?>. 因为你不知道List实际会出现哪种类型。例如,仅以您当前的情况为例。你正在传递一个List<Integer>. 它将成功传递给List<?>. 没有问题。但是您正在向其中添加true, 一种boolean类型。如果编译器允许这样做,它将ClassCastException在运行时抛出。所以,这是不允许的。

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

不,不是那样的。并不是说类型检查是在一定范围内进行的。它在使用泛型的地方强制执行。如果与适当的泛型一起使用,您当前的代码将无法编译,因为您正在尝试将boolean类型添加到List<Integer>. 你为什么希望它起作用?

尝试将您的方法更改为通用方法,您会发现它无法编译:

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

我浏览了泛型教程,但找不到答案。我在这里缺少什么,我应该在哪里阅读它?

嗯,这是 Oracle 的标准教程。这就是你应该阅读的地方。除此之外,您还可以在Java 泛型常见问题解答 - Angelika Langer 中阅读关于泛型的非常好的教程集合。

于 2013-10-24T18:31:05.110 回答