代码之家  ›  专栏  ›  技术社区  ›  PM 77-1 Stones

用于任何列表和泛型/类型擦除方面的方法

  •  0
  • PM 77-1 Stones  · 技术社区  · 11 年前

    首先,创建了一些代码(Java7)来说明我的问题。

    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语言,以在编译时提供更严格的类型检查。。。 “我理解,由于 type erasure 这样的强制执行不可能在运行时发生,所以我上面的代码编译并运行。如果注释行被取消注释,它将触发编译错误,所以我认为 tighter type checks 在相同的方法下有效。这种强制执行的确切范围是什么?它是如何正式定义的?

    1 回复  |  直到 11 年前
        1
  •  3
  •   Rohit Jain    11 年前

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

    它不会编译,因为你不能在 List<?> 。因为你不知道哪种类型 List 真的要来了。例如,仅以您当前的案例为例。你正在通过 List<Integer> 。它将成功传递给 列出<> 。没有问题。但你在补充 true boolean 键入。如果编译器允许,它将抛出 ClassCastException 在运行时。所以,这是不允许的。

    所以我认为在相同的方法中,更严格的类型检查是有效的。这种强制执行的确切范围是什么?

    不,不是那样的。这并不是说类型检查是在一定的范围内进行的。凡是使用泛型的地方都会强制执行。如果与适当的泛型一起使用,您当前的代码将无法编译,因为您正试图添加 布尔值 键入到 列表<整数> 。你为什么期望这样做?

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

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

    我查阅了《遗传学教程》,但没有找到答案。我在这里错过了什么?我应该在哪里读到它?

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