在Java中使用类型化与非类型化ArrayList
之间的区别是什么?
例如,使用ArrayList
CustomObject
:
类型的:
ArrayList<CustomObject> typedArray = new ArrayList<>();
typedArray.add(new CustomObject);
或非打字:
ArrayList<> nonTypedArray = new ArrayList<>();
nonTypedArray.add(new CustomObject);
是否有首选后者?当ArrayList
持有不同的数据类型时有什么不同,例如一个String
,Int
等的ArrayList?
答案 0 :(得分:4)
在第二种方法中,不必仅在第一种方法中添加CustomObject
,否则您将收到编译错误。
ArrayList<CustomObject> typedArray = new ArrayList<>();
typedArray.add(new CustomObject);
这种方法通常是优选的,因为没有机会出现类别施放异常,但在第二种方法中有很高的可能性!
JavaDocs解释得很漂亮:Why to prefer Generics
答案 1 :(得分:3)
使用后一种选择永远不会优先。我认为这甚至不可能。我想你的意思是:
ArrayList nonTypedArray = new ArrayList();
此语法在Java 1.4及更早版本中保留。它仍然为了向后兼容性而编译。
在Java 1.5中引入了泛型,它允许您指定有角度括号之间的类型。
最好使用泛型,因为它更安全。
也就是说,如果你指定
ArrayList<String> typedArray = new ArrayList<String>();
然后你不能不小心将一个整数添加到这个数组列表中;如果你试图添加一个整数,程序将无法编译。
当然,Generics在编译时确保类型安全。在运行时ArrayList<String> typedArray = new ArrayList<String>();
变为ArrayList typedArray = new ArrayList();
。这是为了保持向后兼容性。
答案 2 :(得分:1)
使用typed与非typedArrayList之间的区别是什么? 爪哇?
Typed / Generic ArrayList是一个对象的集合,其中对象的“类型”在有角度的括号中定义。 Java 5中引入了泛型来创建类型安全的集合。 在Generics之前,该集合被称为Untyped / Raw Type Collection,因为无法为编译器指定正在创建的集合的类型。 两者之间的区别是在编译时检测类型安全操作。
在两种情况下,您都要将“CustomObject”类型的对象添加到ArrayList中。在列表中添加元素时没有问题,因为两个列表都将其视为对象。
<强>类型的:强>
ArrayList<CustomObject> typedArray = new ArrayList<>();
typedArray.add(new CustomObject);
<强>无类型:强>
ArrayList<> nonTypedArray = new ArrayList<>();
nonTypedArray.add(new CustomObject);
是否有首选后者?
我不这么认为。建议在创建列表时使用泛型,以确保类型安全操作。
当ArrayList保持不同时有什么不同 datat-ypes,例如String,Int等的ArrayList?
当然,有一个合理的区别。对于无类型列表,您需要在从列表中获取元素时添加类型转换。因为,由于不同类型的元素,编译器有可能在运行时抛出ClassCastException。
答案 3 :(得分:0)
在运行时,绝对没有区别,但是在编译时,使用类型参数可以避免过多的错误,因此最好正确使用泛型。
合理使用原始类型的唯一情况是遗留应用程序,但即使在这种情况下,如果可以,也会尝试使用类型化参数。
答案 4 :(得分:0)
使用类型简化了编码,无需进行投射,也可以有效地存储数据 https://docs.oracle.com/javase/tutorial/java/generics/why.html
答案 5 :(得分:0)
是的,我知道这是一个老帖子。但我想分享一个实例,其中无类型的ArrayList是有用的:当你编写一个应该作用于任意元素类型的函数时。例如,假设您想要创建一个知道如何对数组进行混洗的通用shuffle函数。像这样:
ArrayList<Die> diceRolls = getGetPossibleDiceRolls();
ArrayList<Card> cardDeck = getPossibleCards();
ArrayList<GirlToDate> blackbook = getBlackbook();
shuffle(diceRolls);
shuffle(cardDeck);
shuffle(blackbook);
.
.
void shuffle(ArrayList array) {
int size = array.size();
for (int i=0; i<size; ++i) {
int r = random.nextInt(size - i) + i;
// Swap
Object t = array.get(i);
array.set(i, array.get(r));
array.set(r, t);
}
}
有些人可能会说“是的,但是正确的方法是创建一个类似Shuffleable类型的接口或子类......”但是真的吗?
答案 6 :(得分:0)
在Java 1.7及更高版本中,您通常应该使用如下构造函数:
ArrayList<MyObject> list = new ArrayList<>();
或更普遍的List
对象:
List<MyObject> list = new ArrayList<>();
注意您只指定类型<MyObject>
一次,而不是两次。这使您的代码更易于维护。 <>
使构造函数返回一个ArrayList
,它已经被键入以匹配它所分配的字段/变量 - 因此调用代码中不需要强制转换。
不要使用new ArrayList()
作为构造函数。这将返回无类型 ArrayList
,然后必须将其转换为类型以匹配分配给它的字段/变量。这意味着不必要的类型检查和转换,因此通常会降低性能。