0

如果我想要一个变量,比如说一个列表,它可以用任何类型实例化怎么办?

所以,给定:

List list;

我可以做任何这些:

list = new ArrayList<String>();
list = new Vector<Integer>();
list = new LinkedList<HashMap>();

编辑:或者,我可能正在使用返回原始列表的库。例如,在休眠中:

List result = session.createQuery( "from Event" ).list();

当我想使用 Eclipse 时,会向我发出警告List list

List 是一种原始类型。对泛型类型的引用List<E>应该被参数化

为什么要避免这种情况?

4

6 回答 6

4

当我想要执行上述操作时,Eclipse 给了我这个错误:

我相信eclipse会给你一个警告(黄色下划线),而不是一个错误(红色下划线)。

List 是一种原始类型。对泛型类型 List 的引用应该被参数化

为什么要避免这种情况?

对泛型类型的引用应该被参数化,因为它们提供了更强的类型。这将帮助您在编译时检测到一些问题,否则这些问题只能在执行时检测到。

例如:

List myIntegerList = new ArrayList();
myIntegerList.add(1);
myIntegerList.add("bad bad String");

将毫无问题地编译;但会在执行时给你一个错误。另一方面:

List<Integer> myIntegerList = new ArrayList<Integer>();
myIntegerList.add(1);
myIntegerList.add("bad bad String"); // compiler will show an error here

永远不会编译,因为在尝试将 a 添加String到 a时它会显示一个明显Integer的错误List

于 2013-04-12T04:14:52.557 回答
2

根据 Java 语言,这不是错误,您的 Eclipse 可能已配置为将其标记为错误。Strings现在,您能否确定一个您有时希望保持相同变量的用例Integer?至于为什么会出现此错误,您从中得到的任何东西都必须转换为正确的类型,并存在运行时错误的风险:

List list = new ArrayList<Integer>();
list.add("string"); // no error from compiler
Map m = (Map) list.get(0); // no error from compiler, but runtime error

将此与

List<Integer> list = new ArrayList<Integer>();
list.add("string"); // compile error
Map m = (Map) list.get(0); // compile error 
于 2013-04-12T03:56:31.530 回答
1

仅仅因为你可以做某事并不意味着它是明智的。在什么情况下,你会有一个对象在不同的​​时间可能是 a ArrayList<String>、 aVector<Integer>和 a ?LinkedList<HashMap>不同类型的对象有不同的用途。您可能想要一个具有List<String>实例变量、List<Integer>实例变量和List<Map<K, V>>实例变量的类。然后问题就消失了。

做你建议的事情对你的同事来说将是一个巨大而令人不快的惊喜。让他们开心;不要惹恼他们以展示你的良好记忆力。而且,从现在起六个月后,您是否期望理解您今天编写的代码?谷歌或在这个网站上查找IOCCC。这些程序被编写为聪明,而不是最佳实践的范例。

于 2013-04-12T04:04:16.890 回答
0

您收到此警告是因为您仅参数化了 arraylist 而不是列表对象。所以是通用和非通用的混合体。这可能会导致运行时强制转换异常,从而无法达到泛型的目的。

List<String> list = new ArrayList<>();  //If JDK7, not back comptible

List<String> list = new ArrayList<String>();  //If <=JDK7, back compatible

例如

List<Integer> list1 = new ArrayList<>();
List list2 = new ArrayList<Integer>();

就在您尝试对两个列表执行添加功能时,您可以看到不同之处,

list1.add("sdfsdfd"); //Takes only integer inputs, compilation error
list2.add(obj); //Takes object type, since obj is not integer type, so will throw classcastexception
于 2013-04-12T03:56:48.123 回答
0

试试这个,它会接受任何将 Object 扩展到您的列表的东西。

List<? extends Object> list;
list = new ArrayList<String>();
list = new Vector<Integer>();
list = new LinkedList<Map>();
于 2013-04-12T04:17:44.957 回答
-1

下面的代码应该没问题:

List<?> list; 或者

List<? extends Object> list;

关于java中问号(?)的用法,可以参考Wildcard (Java)

于 2013-04-12T04:27:05.703 回答