首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在ArrayList上指定类型参数的位置

在ArrayList上指定类型参数的位置
EN

Stack Overflow用户
提问于 2017-04-23 01:24:36
回答 2查看 4.4K关注 0票数 4

两边铸造有什么区别:

代码语言:javascript
运行
复制
List <String>myNumbers = new ArrayList<String>();

相对于:

代码语言:javascript
运行
复制
List <String>myNumbers = new ArrayList();

以及:

代码语言:javascript
运行
复制
List myNumbers = new ArrayList<String>();
EN

回答 2

Stack Overflow用户

发布于 2017-04-23 01:48:48

第一个例子是类型安全,这意味着如果您试图将String对象以外的任何内容添加到myNumbers列表中,那么您将得到一个编译器错误。

代码语言:javascript
运行
复制
List <String> myNumbers = new ArrayList<String>();

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

代码语言:javascript
运行
复制
List <String> myNumbers = new ArrayList();

原始类型

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

在JDK1.5中引入泛型时,只保留原始类型,以便与旧版本的java向后兼容。虽然仍然允许使用原始类型,但您应该避免使用它们,原因如下:

  • 通常,原始类型需要强制转换。
  • 原始类型是,而不是类型安全,一些重要的错误只会在运行时出现。
  • 原始类型的表现力较低&不要像参数化类型那样使用自文档的方式。

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

代码语言:javascript
运行
复制
List myNumbers = new ArrayList<String>();

备注--如果您不指定类型,如上面所示,myNumbers列表中的每一项都被视为类型Object

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

从您展示的示例来看,这是首选的方法:

代码语言:javascript
运行
复制
List <String> myNumbers = new ArrayList<String>();

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

意思不是这个意思:

代码语言:javascript
运行
复制
List <String> myNumbers = new ArrayList<String>();

我们可以这样做:

代码语言:javascript
运行
复制
List <String> myNumbers = new ArrayList<>();
票数 2
EN

Stack Overflow用户

发布于 2017-04-23 02:36:53

所以让我们逐个看一遍

代码语言:javascript
运行
复制
List <String>myNumbers = new ArrayList<String>();

这说明myNumbers列表将只存储Strings。这是因为new ArrayList<String>()也限制为'String`‘对象。

接下来是你的第二个例子..。

代码语言:javascript
运行
复制
List <String>myNumbers = new ArrayList();

和以前一样,myNumbers是只存储String对象的约束。不同的是,new ArrayList()将存储任何对象,它是一个原始类型。所以这是编译的。new ArrayList()将保存String对象,因此它会编译。可以在18.2.2 Java语言规范部分中更多地阅读有关约束和类型减少的内容。这属于推论的主题。

第18章.类型推断 各种编译时分析都需要对尚不清楚的类型进行推理。其中主要的是泛型方法适用性测试(§18.5.1)和泛型方法调用类型推断(§18.5.2)。通常,我们将未知类型的推理过程称为类型推理。 在较高层次上,类型推断可以分解为三个过程:

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

最后是你的第三个例子。

代码语言:javascript
运行
复制
List myNumbers = new ArrayList<String>();

这个是最有趣的,因为它引入了类型擦除和原始类型。本质上所发生的是,尽管new ArrayList<String>()是用参数化的String实例化的,但是Java允许忽略这一点以允许原始类型,擦除的概念和规则是如何实现的。至少可以从Java语言规范的4.8和4.6节中推断出这一点。

4.8。原始类型 为了便于与非泛型遗留代码进行接口,可以使用参数化类型(§4.5)的擦除(§4.6)或元素类型为参数化类型的数组类型(§10.1)的擦除(§10.1)作为类型。这种类型称为原始类型。

而且..。

4.6。类型Erasure ...skipping几个要点类型擦除还将构造函数或方法的签名(§8.4.2)映射到 没有参数化类型或类型变量的签名。删除构造函数或方法签名s是由与s同名的签名以及s中给出的所有形式参数类型的擦除组成的签名。方法的返回类型(§8.4.5)和泛型方法或构造函数的类型参数(§8.4.4,§8.8.4)如果删除了方法或构造函数的签名,也会被擦除。删除泛型方法的签名没有类型参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43566460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档