问题:
Java中的原始类型是什么?为什么我经常听到不应该在新代码中使用它们?如果我们不能使用原始类型,还有什么替代方法?如何更好?
问题:
Java中的原始类型是什么?为什么我经常听到不应该在新代码中使用它们?如果我们不能使用原始类型,还有什么替代方法?如何更好?
当前回答
意思是你的列表是一个未指定对象的列表。也就是说,Java不知道列表中有什么类型的对象。然后,当您想要迭代列表时,必须强制转换每个元素,以便能够访问该元素的财产(在本例中为String)。
一般来说,将集合参数化是一个更好的主意,因此您不会遇到转换问题,您只能添加参数化类型的元素,编辑器将为您提供合适的选择方法。
private static List<String> list = new ArrayList<String>();
其他回答
Java中的“原始”类型是一个非泛型类,它处理“原始”对象,而不是类型安全的泛型类型参数。
例如,在Java泛型可用之前,您可以使用这样的集合类:
LinkedList list = new LinkedList();
list.add(new MyObject());
MyObject myObject = (MyObject)list.get(0);
当您将对象添加到列表中时,它并不关心它是什么类型的对象,当您从列表中获取它时,您必须将其显式转换为您期望的类型。
使用泛型,可以删除“未知”因素,因为必须明确指定列表中可以包含的对象类型:
LinkedList<MyObject> list = new LinkedList<MyObject>();
list.add(new MyObject());
MyObject myObject = list.get(0);
注意,对于泛型,您不必强制转换来自get调用的对象,集合是预定义的,只能与MyObject一起使用。这一事实是泛型的主要驱动因素。它将运行时错误源更改为可在编译时检查的内容。
编译器希望您编写以下内容:
private static List<String> list = new ArrayList<String>();
因为否则,您可以将任何您喜欢的类型添加到列表中,使实例化为新的ArrayList<String>()变得毫无意义。Java泛型只是一个编译时特性,因此,如果将新的ArrayList<String>()创建的对象分配给“原始类型”List的引用,它将欣然接受Integer或JFrame元素-对象本身不知道应该包含什么类型,只有编译器知道。
我在做了一些示例练习后发现了这一页,并有着完全相同的困惑。
===============我根据示例提供的代码===============
public static void main(String[] args) throws IOException {
Map wordMap = new HashMap();
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
countWord(wordMap, args[i]);
}
} else {
getWordFrequency(System.in, wordMap);
}
for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
System.out.println(entry.getKey() + " :\t" + entry.getValue());
}
=========================到此代码========================
public static void main(String[] args) throws IOException {
// replace with TreeMap to get them sorted by name
Map<String, Integer> wordMap = new HashMap<String, Integer>();
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
countWord(wordMap, args[i]);
}
} else {
getWordFrequency(System.in, wordMap);
}
for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
Entry<String, Integer> entry = i.next();
System.out.println(entry.getKey() + " :\t" + entry.getValue());
}
}
===============================================================================
这可能更安全,但花了4个小时来驳斥哲学。。。
在这里,我考虑了多个案例,通过这些案例,你可以明确概念
1. ArrayList<String> arr = new ArrayList<String>();
2. ArrayList<String> arr = new ArrayList();
3. ArrayList arr = new ArrayList<String>();
案例1
ArrayList<String>arr它是一个类型为String的ArrayList引用变量,它引用的是一个字符串类型的ArralyList对象。这意味着它只能保存String类型的Object。
它是一个Strict to String,而不是Raw类型,因此它不会引发警告。
arr.add("hello");// alone statement will compile successfully and no warning.
arr.add(23); //prone to compile time error.
//error: no suitable method found for add(int)
案例2
在这种情况下,ArrayList<String>arr是一个严格类型,但您的Object new ArrayList();是原始类型。
arr.add("hello"); //alone this compile but raise the warning.
arr.add(23); //again prone to compile time error.
//error: no suitable method found for add(int)
这里arr是严格类型。所以,当添加整数时,它会引发编译时错误。
警告:-原始类型对象引用到ArrayList的严格类型引用变量。
案例3
在本例中,ArrayList arr是一个原始类型,但Object new ArrayList<String>();是严格类型。
arr.add("hello");
arr.add(23); //compiles fine but raise the warning.
它将向其中添加任何类型的对象,因为arr是一种原始类型。
警告:-严格类型对象引用到原始类型引用的变量。
什么是原始类型,为什么我经常听到不应该在新代码中使用它们?
“原始类型”是使用泛型类而不为其参数化类型指定类型参数,例如使用List而不是List<String>。当泛型引入Java时,几个类被更新为使用泛型。使用这些类作为“原始类型”(不指定类型参数)允许遗留代码仍然编译。
“原始类型”用于向后兼容。不建议在新代码中使用它们,因为使用带有类型参数的泛型类可以实现更强的类型,这反过来可能会提高代码的可理解性,并导致更早地发现潜在问题。
如果我们不能使用原始类型,还有什么替代方法?如何更好?
首选的替代方法是按预期使用泛型类-带有适当的类型参数(例如List<String>)。这允许程序员更具体地指定类型,向未来的维护人员传达关于变量或数据结构的预期用途的更多含义,并允许编译器强制执行更好的类型安全性。这些优点一起可以提高代码质量,并有助于防止引入一些编码错误。
例如,对于程序员希望确保名为“names”的List变量仅包含字符串的方法:
List<String> names = new ArrayList<String>();
names.add("John"); // OK
names.add(new Integer(1)); // compile error