【问题标题】:Why won't Java call the (List<Object>) method, if I have an (Object...) one?如果我有一个 (Object...) 方法,为什么 Java 不调用 (List<Object>) 方法?
【发布时间】:2011-08-15 20:48:14
【问题描述】:

我有以下存储对象数组列表的类。

public class Test {
    private List<Object[]> list = new ArrayList<Object[]>();

    public void addList(Object... obj) {
        list.add(obj);
    }

    public void addList(List<Object> lst) {
        list.add(lst.toArray());
    }
}

当我调用以下内容时,会调用重载方法addList(Object... obj),但我希望调用addList(List&lt;Object&gt; lst)。我该怎么做?

public class Main {
    public static void main(String[] args) {
        Test testObj = new Test();
        List<String> myStrings = new ArrayList<String>();
        myStrings.add("string 1");
        myStrings.add("string 2");
        myStrings.add("string 3");

        // The variable argument method is called but this is a list!
        testObj.addList(myStrings);

    }    
}

【问题讨论】:

  • 您应该考虑放弃List&lt;Object[]&gt; 存储系统。无论您的数据是什么样的,将其建模为类并使用这些类将比尝试推理一堆 Objects 容易得多。

标签: java overloading variadic-functions


【解决方案1】:

List&lt;Object&gt; 更改为List&lt;?&gt; 以捕获任何类型对象的列表。我试过这个,它打印“在列表中”:

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

public class Test {
    private List<Object[]> list = new ArrayList<Object[]>();

    public void addList(Object... obj) {
        System.out.println("in object");
        list.add(obj);
    }

    public void addList(List<?> lst) {
        System.out.println("in List<?>");
        list.add(lst.toArray());
    }

    public static void main(String[] args) {
        Test testObj = new Test();
        List<String> myStrings = new ArrayList<String>();
        myStrings.add("string 1");
        myStrings.add("string 2");
        myStrings.add("string 3");

        // The variable argument method is called but this is a list!
        testObj.addList(myStrings);

    } 
}

【讨论】:

    【解决方案2】:

    这是Java Generic 的问题。您不能将List&lt;String&gt; 分配给List&lt;Object&gt;

    另请参阅:Java Reference assignment with generic lists

    【讨论】:

      【解决方案3】:

      重写你的非可变方法的类型以使用通配符:

      public void addList(List<?> lst) {
          list.add(lst.toArray());
      }
      

      那么List&lt;String&gt;将是参数类型的子类型。

      【讨论】:

        【解决方案4】:

        List&lt;String&gt; 不是List&lt;Object&gt; 的子类。因此,即使您删除了 ... 变体,也永远不会调用重载。

        【讨论】:

          【解决方案5】:

          改变你的方法

          public void addList(List<?> lst) {
              list.add(lst.toArray());
          }
          

          【讨论】:

            猜你喜欢
            • 2016-12-27
            • 1970-01-01
            • 2022-07-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-03
            • 2012-02-22
            相关资源
            最近更新 更多