有人可以向我解释一下在列表类中使用 E 或 Object 有何区别,以及它们的独特用法和定义。 我必须在 LinkedLists 中使用它们来实现方法。
假设 E 来自 element,当编译的方法说它采用某种类型的数组并返回相同类型的数组时,我会考虑在 Collections 中使用泛型。
另一方面,你不能混合橙子和苹果。如果可以将字符串列表传递给需要对象列表的方法,则可以将对象添加到字符串列表中。 (并非所有对象都是字符串)
文字
<E>
指的是泛型。
泛型提供了一种灵活的方法来重用针对不同数据类型泛化的相同代码,同时仍然在编译时保持严格的类型检查。
例如,如果您使用处理
Object
元素的数据结构,则在添加或检索它们时将不具有类型安全性,因为可以传递或返回任何类实例。像这样,您的代码将是容易出错,其中需要首先将元素转换为预期的数据类型才能检索。这种方法会导致转换错误,这些错误仅在运行时带有ClassCastException
。
本质上,泛型帮助开发人员为通用类型参数建立一个定义良好的类型参数,该参数对于每次使用都可以不同。这种方法不仅提供了代码的灵活性和可重用性,而且还提供了编译时的类型安全性,因为编译器能够确保每个操作都符合给定的类型参数。
在这里,我附上一个小例子来展示上面讨论的内容。
public class Main {
public static void main(String[] args) {
//-------- NON-GENERICS APPROACH --------
//Here, any class instance is added to the List
List listObj = new ArrayList();
listObj.add(Integer.valueOf(5));
listObj.add("Hello");
listObj.add(Double.valueOf(3.77));
//At this point, the user of the list cannot retrieve the elements safely,
//without knowing the exact order of how each object has been added
//or without restorting to casting
Integer i1 = listObj.get(0);
String s1 = listObj.get(1);
Double d1 = listObj.get(2);
//-------- GENERICS APPROACH --------
//Defining a generic list working only with Integer
List<Integer> listGenInt = new ArrayList<>();
listGenInt.add(Integer.valueOf(5));
//If I try to add any other type but Integer,
//I would receive an error at compile time
listGenInt.add("Hello");
listGenInt.add(Double.valueOf(3.77));
//Retrieving an element of expected type (Integer)
Integer i2 = listGenInt.get(0);
//Receiving an error as the variables s2 and d2
//do not correspond to the type argument
String s2 = listGenInt.get(1);
Double d2 = listGenInt.get(2);
}
}
在这里,我还提供了一篇由 Angelika Langer 撰写的关于 泛型和参数化类型的精彩文章,以进一步深入探讨该主题。