【问题标题】:Method that works with any List and Generics/Type Erasure aspects适用于任何列表和泛型/类型擦除方面的方法
【发布时间】:2013-10-24 18:27:10
【问题描述】:

首先创建一些代码 (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&lt;?&gt; list 时,它不会编译。我浏览了Generics Tutorial,但找不到答案。我在这里遗漏了什么,我应该在哪里阅读?

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

【问题讨论】:

  • addTrue 应该只适用于List&lt;Boolean&gt;

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


【解决方案1】:

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

它不会编译,因为你不能在List&lt;?&gt; 中添加任何东西。因为你不知道究竟是哪种类型的List 来了。例如,仅以您当前的情况为例。您正在传递List&lt;Integer&gt;。它将成功传递给List&lt;?&gt;。没有问题。但是您正在向其添加trueboolean 类型。如果编译器允许这样做,它将在运行时抛出ClassCastException。所以,这是不允许的。

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

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

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

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

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

嗯,这是来自 Oracle 的标准教程。这就是你应该阅读的地方。除此之外,您还可以在Java Generics FAQs - Angelika Langer. 上阅读关于泛型的非常好的教程集合

【讨论】:

  • 感谢您的回复。 “如果与适当的泛型一起使用”是什么意思?
  • @PM77-1 表示正确使用泛型。就像如果你让你的方法通用,那么当你传递除List&lt;Boolean&gt; 之外的任何东西时,该代码将无法编译。
  • 回复:&lt;T&gt; void。我假设&lt;T&gt; 代表方法的结果类型,因此与void 不兼容。
  • @PM77-1 否,&lt;T&gt; 表示该方法的类型参数。您可以浏览我的答案末尾的泛型教程链接。
  • 谢谢。我相信我现在得到了那个部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
相关资源
最近更新 更多