Java原始类型(例如列表与列表<;对象>;)

Java原始类型(例如列表与列表<;对象>;),java,list,object,generics,collections,Java,List,Object,Generics,Collections,我们的应用程序有数百条警告“xxx是原始类型。对泛型类型xxx的引用应该参数化” 我的问题是,在没有指定类型的地方简单地将类型设置为Object安全吗 一些例子: List list = new List(); Iterator i; 改为: List<Object> = new ArrayList<Object>(); Iterator<Object> i; List=newarraylist(); 迭代器i; 是的,这将实现相同的结果,因为对象位于继承

我们的应用程序有数百条警告“xxx是原始类型。对泛型类型xxx的引用应该参数化”

我的问题是,在没有指定类型的地方简单地将类型设置为Object安全吗

一些例子:

List list = new List();
Iterator i;
改为:

List<Object> = new ArrayList<Object>();
Iterator<Object> i;
List=newarraylist();
迭代器i;

是的,这将实现相同的结果,因为
对象
位于继承链的顶部,原始类型充当
对象
类型

唯一需要注意的是,您将需要使用Java5或更高版本编译和运行


否则,您可以始终
@SuppressWarnings(“rawtypes”)

是的,这将获得相同的结果,因为
对象
位于继承链的顶部,原始类型充当
对象
类型

唯一需要注意的是,您将需要使用Java5或更高版本编译和运行


否则,您可以始终
@SuppressWarnings(“rawtypes”)

如果您的
列表(和其他可概括的类)的所有用法都是原始用法,那么是安全的


如果您的代码将泛型定义与原始定义混合在一起,您需要谨慎。可以使用原始类代替任何泛型类,但反之亦然。因此,例如,如果您有一个带有
List
参数的方法,您当前正在将原始
List
传递给该方法,将其更改为
List
将中断编译。

如果所有
List
(和其他可概括类)的用法都是原始用法,是的,它是安全的


如果您的代码将泛型定义与原始定义混合在一起,您需要谨慎。可以使用原始类代替任何泛型类,但反之亦然。因此,例如,如果您有一个带有
List
参数的方法,并且当前正在将原始
List
传递给该方法,则将其更改为
List
将中断编译。

如果泛型变量是类型绑定的,则并不总是可能。例如,如果您有
MyType
,将
MyType
替换为
MyType
将导致编译错误


还要注意的是,添加
只会消除警告,实际上并不会使代码更安全。

如果泛型变量是类型绑定的,则并不总是可能的。例如,如果您有
MyType
,将
MyType
替换为
MyType
将导致编译错误


另外请注意,添加
只会消除警告,实际上并不会使代码更安全。

否。因为对象在功能上不适用于任何东西。即使您将原始类型转换为基于对象的类型,在代码中迟早还是需要执行转换,以便将这些普通对象转换为程序中更有意义的对象。泛型的设计正是为了让程序员避免代码中的强制转换,因为强制转换是通过友好方式执行的(因此,如果失败,在执行之前您不会注意到)。相反,在编译期间检查泛型类型,确保程序中的所有类型都是一致的,并且在执行时不会产生任何ClassCastException

为什么用显式对象类型替换原始类型并不总是安全的:

假设我们有一个老式容器:

public class MyProvider
{
    private List list;

    public List getList()
    {
        return list;
    }

    public void setList(List list)
    {
        this.list=list;
    }
}
和客户端类(可能位于另一个库中,并且依赖于您的代码,但仍不在您的控制之下):

公共类MyClient
{
公开无效测试()
{
MyProvider provider=新的MyProvider();
List myList1=new ArrayList();
provider.setList(myList1);
List 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;
    }
}
公共类MyProvider
{
私人名单;
公共列表getList()
{
退货清单;
}
公共无效集合列表(列表)
{
this.list=list;
}
}
。。。提供程序部分将删除所有警告并编译为OK,但客户端部分将出现编译错误


寓意:如果有一些依赖的、第三方的代码超出您的控制,请不要更改公共API。否。因为对象在功能上不可用于任何用途。即使您将原始类型转换为基于对象的类型,在代码中迟早还是需要执行转换,以便将这些普通对象转换为程序中更有意义的对象。泛型的设计正是为了让程序员避免代码中的强制转换,因为强制转换是通过友好方式执行的(因此,如果失败,在执行之前您不会注意到)。相反,在编译期间检查泛型类型,确保程序中的所有类型都是一致的,并且在执行时不会产生任何ClassCastException

为什么用显式对象类型替换原始类型并不总是安全的:

假设我们有一个老式容器:

public class MyProvider
{
    private List list;

    public List getList()
    {
        return list;
    }

    public void setList(List list)
    {
        this.list=list;
    }
}
和客户端类(可能位于另一个库中,并且依赖于您的代码,但仍不在您的控制之下):

公共类MyClient
{
公开无效测试()
{
MyProvider provider=新的MyProvider();
List myList1=new ArrayList();
provider.setList(myList1);
List 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;
    }
}
公共类MyProvider
{
私人名单;
公共列表getList()
{
退货清单;
}
公共无效集合列表(列表)
{
this.list=list;
}
}
。。。提供者部分将删除所有警告并编译OK,但客户端部分将上升