0

我看到一个arry列表设置如下

private ArrayList<Student> students; //instance variable

public CollegeCommunity()//constructor

{
    students = new ArrayList<Student>();
}

如下

 ArrayList exampleArray = new ArrayList();

我理解为什么一个有一个实例变量/构造函数而另一个只是简单地声明但我不确定为什么第一个包含<Student>而另一个没有这两者有<...> 什么区别?

4

5 回答 5

3

不同之处在于称为泛型的语言功能,在此处的 Java 教程跟踪中对此进行了说明。

exampleArray使用泛型类的原始类型声明ArrayList...

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

原始类型没有泛型类型信息,因此与引入泛型之前类的使用相同。

另一方面,students使用泛型参数化类型

泛型类型是通过类型参数化的泛型类或接口。

泛型很有用,因为它们允许编译器拥有更多类型信息,从而通过允许它有效地推断类型来简化编程,这用于强制强类型化和消除强制转换

原始ArrayList几乎等同ArrayList<Object>. 不同之处在Effective Java中突出显示。

原始类型List和参数化类型之间有什么区别List<Object>

粗略地说,前者选择退出泛型类型检查,而后者明确告诉编译器它能够保存任何类型的对象。虽然您可以将 a 传递List<String>给 type 的参数List,但不能将它传递给 type 的参数List<Object>。泛型有子类型规则,List<String>是原始类型的子类型List,但不是参数化类型的子类型List<Object>

因此,如果您使用像 List 这样的原始类型,则会失去类型安全性,但如果使用像List<Object>.

于 2012-08-05T20:52:13.207 回答
0

第一个 ArrayList 声明定义了泛型类型,而 exampleArray 没有。建议尽可能使用泛型来避免强制转换:

例如

ArrayList<Student> students = ...;
Student student = students.get(0);

相对:

ArrayList exampleArray = ...;
Example example = (Example)exampleArray.get(0);
于 2012-08-05T20:55:01.303 回答
0

<Students>下一个的原因ArrayList是因为您需要指定将持有data的类型。ArrayList在这种情况下,这个人告诉 java 他想要一个ArrayList包含类的数据类型Students

不这样做是行不通的。

于 2012-08-05T20:57:22.207 回答
0

区别只是对编译器的提示。该声明new ArrayList<Student>() 强制执行这样一个事实,即您将仅将Student类的实例存储在指定的集合中。这允许 Java 保留strong type-safety泛型。

在运行时,由于 Java 具有类型擦除功能,因此不会发生任何变化,但是这种强约束将对您有所帮助:每当您尝试使用与您用来声明它的时间不同的时间的集合时,编译器都会引发错误。它被称为参数多态性

相反,原始声明new ArrayList()实例化了一个列表,在该列表上没有假设您要在其中存储的对象的类型:这意味着可以存储所有内容,但是在检索对象时需要回退对象。此外,您不会有任何类型安全性,因为在编译时编译器将无法检查您将尝试在集合中插入的内容。

于 2012-08-05T20:59:24.920 回答
0

students正在使用所谓的泛型。泛型约束可以传递给ArrayList. exampleArray没有指定类型。

于 2012-08-05T20:49:50.403 回答