我已经看到如下设置的arry列表
private ArrayList<Student> students; //instance variable
public CollegeCommunity()//constructor
{
students = new ArrayList<Student>();
}
如下
ArrayList exampleArray = new ArrayList();
我理解为什么一个人有一个实例变量/构造函数而另一个只是简单声明但我不确定为什么第一个包含<Student>
而另一个没有<...>
这两者有什么区别?
答案 0 :(得分:3)
区别在于称为泛型的语言特性,Java Tutorials trail here中对此进行了解释。
exampleArray
使用通用类ArrayList
的{{3}}声明...
原始类型是没有任何类型参数的泛型类或接口的名称。
原始类型具有 no 泛型类型信息,因此在引入泛型之前与类的使用相同。
另一方面,students
使用通用raw type。
泛型类型是一个通过类型参数化的泛型类或接口。
parameterized type因为它们允许编译器拥有更多的类型信息,从而通过允许它有效地推断类型来简化编程,这些类型用于强制执行强类型和消除管型强>
原始ArrayList
几乎等同于ArrayList<Object>
。区别在于 Effective Java 。
原始类型
List
与参数化类型List<Object>
之间有什么区别?松散地说,前者选择了泛型类型检查,而后者明确告诉编译器它能够保存任何类型的对象。虽然您可以将
List<String>
传递给类型为List
的参数,但您无法将其传递给List<Object>
类型的参数。泛型有子类型规则,List<String>
是原始类型List
的子类型,但不是参数化类型List<Object>
的子类型。因此,如果使用像List这样的原始类型,则会丢失类型安全性,但如果使用
List<Object>
之类的参数化类型则不会失去类型安全性。
答案 1 :(得分:0)
students
正在使用所谓的泛型。泛型约束可以传递给ArrayList
的类型。 exampleArray
未指定类型。
答案 2 :(得分:0)
第一个ArrayList声明定义了泛型类型,而exampleArray没有。建议尽可能使用泛型来避免铸造:
E.g。
ArrayList<Student> students = ...;
Student student = students.get(0);
与
ArrayList exampleArray = ...;
Example example = (Example)exampleArray.get(0);
答案 3 :(得分:0)
<Students>
旁边有ArrayList
的原因是因为您需要指定data
将保留的ArrayList
类型。在这种情况下,该人告诉java他希望ArrayList
包含类Students
的数据类型
如果不这样做就行不通。
答案 4 :(得分:0)
差异只是编译器的一个提示。宣言new ArrayList<Student>()
强制执行以下事实:您将在指定集合中仅存储Student
类的实例。这允许Java通过泛型保持strong type-safety
。
在运行时没有不会改变,因为Java有type erasure但是这个强大的约束会帮助你:编译器会在你尝试使用不同时间的集合时引发错误与您过去宣称的相比。它被称为parametric polymorphism。
原始声明new ArrayList()
实例化一个列表,在该列表中没有假设您要存储在其中的对象类型:这意味着可以存储所有内容,但是当您需要回滚对象时检索它们。此外,您不会有任何类型安全性,因为在编译时编译器将无法检查您将尝试在集合中插入的内容。