我们的应用程序有数百条警告“xxx是原始类型。参考通用类型xxx<>应参数化”
我的问题是,在未指定类型的地方简单地将类型设置为Object是否安全?
一些例子:
List list = new List();
Iterator i;
更改为:
List<Object> = new ArrayList<Object>();
Iterator<Object> i;
答案 0 :(得分:3)
是的,这将获得相同的结果,因为Object
位于继承链的顶部,而原始类型则充当Object
类型。
唯一需要注意的是,您需要使用Java 5或更高版本进行编译和运行。
您可以随时@SuppressWarnings("rawtypes")
。
答案 1 :(得分:1)
如果所有您List
(以及其他可推广类)的用法是原始用法,是的,它是安全的。
如果您的代码将基因定义与原始定义混合在一起,那么您应该谨慎行事。可以使用原始类代替任何generelized类,但不能反过来。因此,例如,如果您有一个带有List<String>
参数的方法,您当前正在将原始List
传递给它,则将其更改为List<Object>
将会破坏您的编译。
答案 2 :(得分:0)
如果通用变量是类型绑定的,那么它并不总是可行的。例如,如果您有MyType<T extends Number>
,则将MyType
替换为MyType<Object>
将导致编译错误。
另请注意,添加<Object>
只是为了摆脱警告,而不是让代码更安全。
答案 3 :(得分:0)
没有。因为对象在功能上不适用于任何事物。即使您将原始类型转换为基于对象,迟早会在代码中转换,但您需要执行强制转换以将这些纯对象转换为程序中更有意义的对象。并且仿制药的构思正是为了让程序员避免代码中的强制转换,因为演员表是 dinamically (因此,如果它失败了,你就会赢得&#t; t通知直到执行)。相反,在编译期间检查泛型类型,确保程序中的所有类型都是连贯的,并且不会在执行中产生任何ClassCastExceptions。
为什么用explic对象类型替换原始类型并不总是安全的:
假设我们有一个旧式容器:
public class MyProvider
{
private List list;
public List getList()
{
return list;
}
public void setList(List list)
{
this.list=list;
}
}
一个客户端类(可能在另一个库中并依赖于您的代码,仍然不在您的控制之下):
public class MyClient
{
public void test()
{
MyProvider provider=new MyProvider();
List<String> myList1=new ArrayList<String>();
provider.setList(myList1);
List<String> myList2=provider.getList();
}
}
此方案在提供者和客户端都产生警告,仍然编译并执行OK。
但是,如果我们将提供商的公共API更改为基于对象:
public class MyProvider
{
private List<Object> list;
public List<Object> getList()
{
return list;
}
public void setList(List<Object> list)
{
this.list=list;
}
}
...提供者部分将删除所有警告并编译正常,但客户端部分将上升编译错误。
道德:如果您的控制范围之外可能存在某些依赖的第三方代码,则永远不要更改公共API。
答案 4 :(得分:0)
完全没问题,但如果列表包含不同类型的值(即带字符串的布尔值),则代码中可能会出现转换错误。简单的例子:当你尝试在控制台上打印时,如果你添加一个布尔值和一个字符串,你将获得ClassCastException
:
List l = new ArrayList();
l.add("My string"); // Completely fine!
l.add(true); // fine
System.out.println(l.get(0)); // will output 'My string'
System.out.println(l.get(1)); // will raise ClassCastException