如果我想要一个变量,比如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>
的引用应该参数化
为什么要避免这种情况?
答案 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)