繁体   English   中英

在ArrayList上指定类型参数的位置[重复]

[英]Where to specify type parameter on ArrayList [duplicate]

两侧铸造之间有什么区别:

List <String>myNumbers = new ArrayList<String>();

与:

List <String>myNumbers = new ArrayList();

和:

List myNumbers = new ArrayList<String>();

第一个示例是类型安全的,这意味着如果尝试将除String对象之外的任何内容添加到myNumbers列表中,则会出现编译器错误。

List <String> myNumbers = new ArrayList<String>();

第二个示例也是类型安全的,编译器将确保仅将String类型的对象存储在myNumbers列表中。

List <String> myNumbers = new ArrayList();

原始类型

原始类型是没有任何类型参数的泛型类或接口的名称。

在JDK 1.5中引入泛型时,保留原始类型只是为了与Java的较早版本向后兼容。 尽管仍然允许使用原始类型,但出于以下原因,您应避免使用它们:

  • 通常原始类型需要强制转换
  • 原始类型不是类型安全的,某些重要类型的错误只会在运行时出现。
  • 原始类型的表现力较低,并且不会以与参数化类型相同的方式进行自我记录。

最后一个示例是原始类型,这意味着我们可以将所有类型的对象添加到myNumbers列表中,但是,应尽可能避免使用它们。

List myNumbers = new ArrayList<String>();

注意 -如上所示,如果您未指定类型,则myNumbers列表中的每个项目都将被视为Object类型。

在哪里指定ArrayList上的类型参数?

从示例中可以看出,这是首选方式:

List <String> myNumbers = new ArrayList<String>();

但是,只要编译器可以从上下文中推断类型实参,就可以用空的类型实参集( < > )替换调用通用类的构造函数所需的类型实参。

代替这个意思:

List <String> myNumbers = new ArrayList<String>();

我们做得到:

List <String> myNumbers = new ArrayList<>();

因此,让我们经历每个

List <String>myNumbers = new ArrayList<String>();

这说明myNumbers列表将仅存储Strings 之所以进行编译,是因为new ArrayList<String>()也仅约束为“ new ArrayList<String>() ”对象。

继续第二个示例...

List <String>myNumbers = new ArrayList();

与之前相同, myNumbers被限制为仅存储String对象。 不同的是, new ArrayList()将存储任何对象,这是原始类型。 这样就可以编译了。 new ArrayList()将保存String对象,因此可以进行编译。 在Java语言规范的18.2.2节中可以了解有关约束和类型缩减的更多信息。 这属于推论主题。

第18章类型推断

各种编译时分析需要对尚不知道的类型进行推理。 其中主要的是通用方法适用性测试(第18.5.1节)和通用方法调用类型推断(第18.5.2节)。 通常,我们将推理未知类型的过程称为类型推断。

从高层次上讲,类型推断可以分解为三个过程:

  • 归约采用关于表达式或类型的兼容性声明(称为约束公式),并将其简化为推理变量的一组边界。 通常,约束公式可简化为其他约束公式,必须递归地将其缩减。 遵循一个过程来识别这些附加约束公式,并最终通过一个边界集来表达条件,在这些条件下,用于推断类型的选择将使每个约束公式为真。

最后是第三个例子

List myNumbers = new ArrayList<String>();

这是最有趣的一种,因为它介绍了类型擦除和原始类型。 本质上发生的事情是,即使使用参数化String实例化了new ArrayList<String>() ,Java仍允许忽略此参数以允许使用Raw Types,并且擦除的概念和规则是实现方式。 至少这可以从Java语言规范的4.8和4.6节中得出。

4.8。 原始类型

为了促进与非通用遗留代码的接口,可以将参数化类型(第4.5节)的擦除(第4.6节)或元素类型为参数化类型的数组类型的擦除(第10.1节)用作类型。 。 这种类型称为原始类型。

此外...

4.6。 类型擦除

...跳过几个要点

类型擦除还将构造函数或方法的签名(第8.4.2节)映射到
没有参数化类型或类型变量的签名。 删除构造函数或方法签名s是由与s相同的名称以及s中给出的所有形式参数类型的擦除组成的签名。

如果擦除方法或构造函数的签名,则方法的返回类型(第8.4.5节)和通用方法或构造函数的类型参数(第8.4.4节,第8.8.4节)也将被擦除。

通用方法签名的擦除没有类型参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM