当前位置: 首页 > 知识库问答 >
问题:

为什么在Java泛型中,集合的右侧类型没有任何影响?

董建德
2023-03-14

使用Java的泛型特性,我创建了一个List对象,在左侧,我使用原始类型List,在右侧,我使用泛型类型ArrayList

List myList=new ArrayList<String>();

并且我在list对象中添加了一个int值。

myList.add(101);
List<String> myList=new ArrayList();
myList.add(101);//The method add(int, String) in the type List<String> is not applicable for the arguments (int)

共有1个答案

虞俊美
2023-03-14

如果左侧没有提供泛型类型参数,则list将声明为原始类型。这意味着编译器不知道在该列表中存储哪些内容是合法的或不合法的,而是依赖于程序员执行适当的instanceof检查和强制转换。

原始类型还具有删除它们出现在的类中的所有泛型类型信息的效果。

JLS提供了对原始类型的更详细的了解。您应该会在IDE中或编译器中看到关于分配给raw类型的警告:

为了确保总是标记潜在的违反类型规则的行为,某些对原始类型成员的访问将导致编译时未经检查的警告。访问原始类型的成员或构造函数时的编译时未检查警告的规则如下:

在赋值给字段时:如果左侧操作数的类型是raw类型,那么如果erasure更改了字段的类型,则会出现编译时未检查的警告。

调用方法或构造函数时:如果要搜索的类或接口的类型(§15.12.1)是raw类型,那么如果erasure更改了方法或构造函数的任何形参类型,则会出现编译时未检查的警告。

当形参类型在erasure下没有更改(即使结果类型和/或抛出子句更改)时,方法调用、从字段读取或创建原始类型的类实例时,不会出现编译时未检查的警告。

 类似资料:
  • 问题内容: 免责声明:我现在只和Go玩了一天,所以我很有可能错过了很多。 有谁知道为什么Go中没有对泛型/模板/ whatsInAName的真正支持?因此,有一个通用的,但这是由编译器提供的,而Go程序员无法编写自己的实现。关于如何使Go尽可能正交的所有讨论,为什么我可以使用通用类型而不创建新类型? 尤其是在函数式编程方面,有lambda甚至闭包,但是在缺少泛型的静态类型系统中,我该如何编写泛型高

  • 问题内容: 如果我有一个通用类: 我想实例化几个项目,例如… …并将它们添加到集合中。如何定义集合,使其可以容纳泛型类型列表?然后,我想在某个时刻迭代集合,并使用Value属性。可能? 问题答案: 让您的泛型类从非泛型基类继承,或实现一个非泛型接口。然后,您可以拥有此类型的集合,并将其转换为用于访问集合内容的任何代码。 这是一个例子。

  • 问题内容: 在解决了之前的问题的基础上,但又导致了另一个问题。如果协议/类类型存储在集合中,则取回并实例化它们会引发错误。下面是一个假设的例子。该范例基于“程序到接口而不是实现”,“程序到接口” 编辑 -我当前的解决方法是遍历集合,但是由于api必须知道各种实现,所以这当然是有限的。另一个限制是这些类型的子类(例如PersianCat,GermanShepherd)将不会调用其重写的函数,否则我将

  • 问题内容: 在Java中,Map接口定义为 为什么不? 我刚遇到一个讨厌的错误,因为使用了错误的类型密钥。我认为泛型的目的是在编译期间及早捕获类型错误。这会达到目的吗? 问题答案: 凯文·布罗里恩(Kevin Bourrillion)不久前就在博客上发表了文章。摘要: 一致地,除非有必要防止集合损坏,否则Java Collections Framework(以及Google Collections

  • 问题内容: 我正在使用泛型编写某些东西,令我惊讶的是,我发现这行不通: 那我不能实例化泛型吗?没有任何方法可以做到这一点吗? 问题答案: 是的,这真是令人讨厌。 我使用的解决方法是强制客户端在构造新类时传递类-即 然后您可以使用。

  • 问题内容: 为什么以下代码会编译?该方法返回该类型或其子类的实例。类中的代码调用该方法。编译器允许将返回值存储到类型的变量(显然不在的层次结构中)。 即使在擦除类型之后, 返回类型也不应该仍然是的实例 吗? 该方法的字节码为: 编辑:一致地替换为。 问题答案: 这实际上是合法的类型推断*。 我们可以将其简化为以下示例(Ideone): 因为是接口,所以允许编译器推断(无意义的,实际上是)交集类型。