在Java 7中使用非参数化泛型类型有什么问题?

时间:2013-04-12 03:51:00

标签: java generics types

如果我想要一个变量,比如List,可以使用任何类型进行实例化,该怎么办?

所以,给定:

List list;

我可以做以下任何一件事:

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

修改: 或者,我可能正在使用返回原始列表的库。例如,在Hibernate中:

List result = session.createQuery( "from Event" ).list();
当我想使用List list时,Eclipse会给我这个警告:

  

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

为什么要避免这种情况?

6 个答案:

答案 0 :(得分:3)

  

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

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

  

列表是原始类型。对泛型类型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

永远不会编译,因为在尝试将String添加到Integer的{​​{1}}时会显示明显的错误。

答案 1 :(得分: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 

答案 2 :(得分:1)

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

做你的建议对你的同事来说将是一个巨大而令人不快的惊喜。让他们开心;不要惹恼他们,以展示你的美好回忆。而且,从现在开始的六个月,您是否希望了解您今天编写的代码? Google或查看此网站 IOCCC 。这些程序写得很聪明,而不是最佳实践的范例。

答案 3 :(得分:0)

您收到此警告是因为您仅对arraylist进行参数化而不是列表对象。所以是泛型和非泛型的混合。这可能导致运行时转换异常,从而无法实现泛型。

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

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

e.g。

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

答案 4 :(得分:0)

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

List<? extends Object> list;
list = new ArrayList<String>();
list = new Vector<Integer>();
list = new LinkedList<Map>();

答案 5 :(得分:-1)

下面的代码应该没问题:

List<?> list;

?

要在java中使用问号(?),可以参考Wildcard (Java)