假设您有一个返回 ArrayList 的 String 对象的方法:
public ArrayList<String> foo() {
ArrayList<String> list = new ArrayList<>();
// ... fill list ...
return list;
}
这就是您通常1在 Java 5+ 中声明方法的方式(因为添加了泛型)。但是您没有必须这样做。您可以将方法声明为:
public ArrayList foo() {
// ... code ...
return list;
}
这意味着您正在使用raw types。除非您正在与旧版(Java 5 之前)库/应用程序进行交互,否则您 never want to use raw types。原因是原始类型(几乎?)等同于返回ArrayList<Object>。您刚刚失去了泛型提供的所有类型安全性。泛型的原因是提供编译时2 类型检查,这样您就不会意外使用错误的类型。例如,您现在可以将Dog 添加到foo 返回的ArrayList,即使您希望它只包含String 对象。此外,使用返回的ArrayList 的代码不能保证ArrayList 内只有String 对象,这可能会导致各种令人头疼的问题。
您可以通过强制转换来绕过原始类型:
String element = (String) foo().get(0);
但是,无论如何,这基本上是通用代码编译的内容;除非您不再具有编译时安全性。
如果元素类型也是通用的,那么是的,您也希望返回该信息。假设您返回 ArrayList 的 Supplier 对象。每个Supplier 都会返回所需的String 对象。
public ArrayList<Supplier<String>> foo() {
// ... code ...
}
请务必在此处给出Supplier 的通用签名,以便您可以执行以下操作:
for (Supplier<String> sup : foo()) {
String str = sup.get();
// .. do something with "str" ...
}
如果您返回ArrayList<Supplier>,那么每个Supplier.get() 将返回一个Object。你又失去了所有类型安全。
1.实际上,在几乎所有情况下,您都希望返回 List 而不是 ArrayList。最好program to an interface。
2。由于type erasure,它仅在编译时有效。另见this。