【问题标题】:List<Object> and List<?>List<Object> 和 List<?>
【发布时间】:2012-04-16 19:24:44
【问题描述】:

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

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

其次,我有一个返回List&lt;?&gt; 的方法,我如何将其转换为List&lt;Object&gt;,我可以简单地转换它吗?

谢谢!

【问题讨论】:

  • 好吧,如果你们说List&lt;?&gt;不能实例化,那方法怎么能返回呢?
  • 值得注意的是Arrays.asList(T... a) 返回一个List&lt;T&gt;。您可以使用 List&lt;Object&gt; li = Arrays.asList(1, 2, "3"); 初始化 List 以节省一些输入,尽管返回的 List 将是固定大小并由数组支持:docs.oracle.com/javase/7/docs/api/java/util/…...

标签: java list object arraylist


【解决方案1】:
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);
             }

        }
    }

}

【讨论】:

    【解决方案2】:

    要回答您的第二个问题,是的,您可以将List&lt;?&gt; 转换为任何类型的List&lt;Object&gt;List&lt;T&gt;,因为?(通配符)参数表明列表包含同质集合任何 Object。但是,在编译时无法知道 type 是什么,因为它只是导出 API 的一部分 - 这意味着您看不到 List&lt;?&gt; 中插入的内容。

    以下是你制作演员表的方法:

    List<?> wildcardList = methodThatReturnsWildcardList();
    // generates Unchecked cast compiler warning
    List<Object> objectReference = (List<Object>)wildcardList;
    

    在这种情况下,您可以忽略警告,因为要在泛型类中使用对象,它必须是 Object 的子类型。假设我们试图将其转换为 List&lt;Integer&gt;,而它实际上包含 Strings 的集合。

    // 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();
    

    【讨论】:

      【解决方案3】:
      List<Object> object = new List<Object>();
      

      你不能这样做,因为 List 是一个接口,你不能创建任何接口的对象,或者换句话说你不能实例化任何接口。此外,您可以将实现 List 的任何类对象分配给它的引用变量。例如,您可以这样做:

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

      这里的ArrayList是一个实现List的类,你可以使用任何实现的类列表

      【讨论】:

        【解决方案4】:

        List 是一个接口,所以你不能实例化它。改用它的任何实现,例如

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

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

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

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

        在使用List&lt;Object&gt; 时,此声明无效,因为它将是类型不匹配的。

        【讨论】:

          【解决方案5】:

          为什么我不能这样做:

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

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

          以下是创建ArrayList 实例的方法:

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

          我有一个返回List&lt;?&gt; 的方法,我如何将它变成List&lt;Object&gt;

          向我们展示相关代码,我会更新答案。

          【讨论】:

          • 返回List&lt;?&gt; 的方法来自外部库,我无法访问代码。我只知道它曾经返回一个List&lt;Object&gt;,然后他们更新了代码,现在它返回了一个List&lt;?&gt;,基本上破坏了我所有的编码。
          • 答案没有充分解决问题的第二部分。举个例子怎么样?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-11
          • 2018-09-22
          相关资源
          最近更新 更多