列表与列表<对象>

Var*_*har 12 java generics

为什么我们在使用时会丢失类型安全性List而不是在使用时List<Object>?他们基本上不一样吗?

编辑:我发现以下给出了编译错误

public class TestClass
{
    static void func(List<Object> o, Object s){
        o.add(s);
    }

    public static void main(String[] args){
        func(new ArrayList<String>(), new Integer(1));
    }
}
Run Code Online (Sandbox Code Playgroud)

而事实并非如此

public class TestClass
{
    static void func(List o, Object s){
        o.add(s);
    }

    public static void main(String[] args){
        func(new ArrayList<String>(), new Integer(1));
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么?

Mik*_*uel 5

为什么我们在使用时会丢失类型安全性List而不是在使用时List<Object>?他们基本上不一样吗?

不,他们不是一回事.

如果您要提供API,

class API {
  static List<Object> getList() { ... }
  static void modifyList(List<Object> l) { ... }
}
Run Code Online (Sandbox Code Playgroud)

并且客户使用它不正确

List<Integer> list = API.getList();
API.modifyList(list);
for (Integer i : list) { ... }  // Invalid
Run Code Online (Sandbox Code Playgroud)

那么当你的API指定List<Object>他们得到一个编译时错误,但他们没有当API.getList()回报List,并API.modifyList(list)采取List不泛型类型参数.

编辑:

在评论中你提到了改变

void func(List<Object> s, Object c) { s.add(c); }
Run Code Online (Sandbox Code Playgroud)

void func(List s, Object c) { s.add(c); }
Run Code Online (Sandbox Code Playgroud)

以便

func(new List<String>(), "");
Run Code Online (Sandbox Code Playgroud)

会工作.

这违反了类型安全.这种类型安全的方法是

<T> void func(List<? super T> s, T c) { s.add(c); }
Run Code Online (Sandbox Code Playgroud)

这基本上说func是一个参数化函数,它List的类型可以是T的任何超类,类型为T的值,并将值添加到列表中.


Meh*_*dad 5

List您不知道某种类型的列表.它可能是一个List<String>,List<Integer>等等.
它实际上等同于List<?>,或者List<? extends Object>,除了它没有记录这个事实.它仅支持向后兼容性.

List<Object>是一个对象列表.任何类型的任何对象都可以放在其中,例如,它只接受字符串.List<String>

所以不,他们不是一回事.