List<Object> and List<?>

28

我有两个问题,实际上... 首先,为什么我不能这样做:

List<Object> object = new List<Object>();

其次,我有一个返回 List<?> 的方法,如何将其转换为 List<Object>,我能直接强制转换吗?

谢谢!


好的,如果你们说 List<?> 不能被实例化,那么这个方法怎么能返回它呢? - Christopher
值得注意的是,Arrays.asList(T... a) 返回一个 List<T>。你可以使用 List<Object> li = Arrays.asList(1, 2, "3"); 来初始化 List,以节省一些打字时间,尽管返回的 List 将是固定大小并由数组支持:https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#asList(T...) - Yibo Yang
5个回答

48

Why cant I do this:

List<Object> object = new List<>();

你无法这样做,因为List是一个接口,而接口无法实例化。只有(具体的)类可以。实现List的具体类的例子包括ArrayListLinkedList等。

下面是如何创建ArrayList实例的方法:

List<Object> object = new ArrayList<>();

我有一个返回 List<?> 的方法,我该如何将它转换为一个 List<Object>
请展示相关的代码,我会更新答案。

返回一个 List<?> 的方法来自外部库,我无法获取其代码。我只知道它曾经返回一个 List<Object>,然后他们更新了代码,现在它返回一个 List<?>,从本质上打破了我的所有编码。 - Christopher
答案没有充分回答问题的第二部分。能否举个例子? - Derek Mahar

6
List<Object> object = new List<Object>();

由于List是一个接口,您不能创建任何接口的对象,也就是说,您不能实例化任何接口。此外,您可以将实现List的类的任何对象分配给其引用变量。例如,您可以这样做:

list<Object> object = new ArrayList<Object>();

这里的ArrayList是一个实现了List接口的类,你可以使用任何实现了List接口的类。


2

列表是一个接口,因此您无法实例化它。使用其任何实现代替,例如:

List<Object> object = new List<Object>();

关于列表: 你可以使用任何对象作为其实例的通用参数:

List<?> list = new ArrayList<String>();

或者

List<?> list = new ArrayList<Integer>();

使用 List<Object> 进行声明是无效的,因为它会导致类型不匹配。


1
回答你的第二个问题,是的,你可以将 List<?> 强制转换为任何类型的 List<Object>List<T>,因为 ?(通配符)参数表示该列表包含一个同种类型的任何对象集合。然而,在编译时无法知道 type 是什么,因为它只是导出 API 的一部分 - 这意味着你看不到插入到 List<?> 中的内容。
以下是强制转换的方法:
List<?> wildcardList = methodThatReturnsWildcardList();
// generates Unchecked cast compiler warning
List<Object> objectReference = (List<Object>)wildcardList;

在这种情况下,您可以忽略警告,因为为了将对象用于通用类,它必须是Object的子类型。假设我们试图将其转换为List<Integer>,而实际上它包含一组String
// this code will compile safely
List<?> wildcardList = methodThatReturnsWildcardList();
List<Integer> integerReference = (List<Integer>)wildcardList;

// this line will throw an invalid cast exception for any type other than Integer
Integer myInteger = integerRefence.get(0);

记住:泛型在运行时被擦除。你不会知道集合包含什么,但是你可以获取一个元素并调用 .getClass() 来确定它的类型。
Class objectClass = wildcardList.get(0).getClass();

0
package com.test;

import java.util.ArrayList;
import java.util.List;

public class TEst {

    public static void main(String[] args) {

        List<Integer> ls=new ArrayList<>();
        ls.add(1);
        ls.add(2);
        List<Integer> ls1=new ArrayList<>();
        ls1.add(3);
        ls1.add(4);
        List<List<Integer>> ls2=new ArrayList<>();
        ls2.add(ls);
        ls2.add(ls1);

        List<List<List<Integer>>> ls3=new ArrayList<>();
        ls3.add(ls2);


        m1(ls3);
    }

    private static void m1(List ls3) {
        for(Object ls4:ls3)
        {
             if(ls4 instanceof List)    
             {
                m1((List)ls4);
             }else {
                 System.out.print(ls4);
             }

        }
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接