【问题标题】:Why it compiles "List<String> lst; Object[] o = lst;" if List<String> is varargs?为什么它编译“List<String> lst; Object[] o = lst;”如果 List<String> 是可变参数?
【发布时间】:2016-12-16 08:15:00
【问题描述】:
public class VarargsParamVsLocalVariable {

    static void f(List<String>... stringLists) {
        // compiles fine! No problems in Runtime as well.
        Object[] array = stringLists; 
    }

    //but the same fails if List<String> is not a vararg parameter
    public static void main(String[] args) {
        List<String> stringLists; 
        List<String> stringLists1 = new ArrayList<>();
        //below lines give: "cannot convert from List<String> to Object[]"
        Object[] array = stringLists; // compile error!
        Object[] array1 = stringLists1; // compile error!
    }
}  

 // Why I can assign List<String> variable to Object[] variable if List<String> variable is a vararg parameter? 

如果 List 变量是可变参数,为什么我可以将 List 变量分配给 Object[] 变量?

【问题讨论】:

标签: java variadic-functions


【解决方案1】:

因为像List&lt;String&gt;... stringLists 这样的Varargs 在某种程度上等同于像List&lt;String&gt;[] stringLists 这样的数组

要编译你的代码,你应该创建一个array 作为下一个:

Object[] array1 = {stringLists1};

对于stringLists,你需要先初始化它,否则即使你尝试像上面那样创建一个数组,它也不会编译。

出于同样的原因,public static void main(String[] args) { 可以被重写:

public static void main(String... args) {

【讨论】:

    【解决方案2】:

    因为 Java 最初没有可变参数。它们被添加的方式是将 varargs 参数视为一个数组。

    实际上,这个

    static void f(List<String>... stringLists)
    

    ...与

    相同
    static void f(List<String>[] stringLists)
    

    ...因此它与 Object[] 的赋值兼容。

    【解决方案3】:

    任何引用类型的可变参数都可以分配给Object 数组。在您的特定情况下,Object 数组的每个元素都是 List&lt;String&gt;

    如果您更改数组的类型,您的代码会更清晰(并且类型安全):

    static void f(List<String>... stringLists) {
        List<String>[] array = stringLists; 
    }
    

    这表明您没有将List 转换为数组。您只需将零个、一个或多个Lists 分配给Lists 数组。

    【讨论】:

      【解决方案4】:

      在这段代码中:

      static void f(List<String>... stringLists) {
          // compiles fine! No problems in Runtime as well.
          Object[] array = stringLists; 
      }
      

      stringLists 是一个由List&lt;String&gt; (List&lt;String&gt;[]) 组成的数组,但这个数组的每个 List 基本上都是一个 Object。

      所以你必须知道这一点,List&lt;String&gt; 可以转换为一个对象。列表数组 (List[]) 可以转换为对象。任何数组、列表、哈希表...都可以转换为对象,这就是它顺利通过的原因。

      【讨论】:

        【解决方案5】:

        varargs 基本上是数组的语法糖,即编译器将实际创建并初始化 vararg 类型的数组(通过)。

        因此,在您的可变参数f 方法中,stringLists 是可变参数,它实际上是一个数组 (List&lt;String&gt;[]),可以分配给 Object[]

        【讨论】:

          【解决方案6】:

          Varargs 是作为将任意数量的值传递给方法的方式创建的。以前是通过将值放入该数组中来使用数组来实现的。

          所以 Varargs 只是实现相同目的的另一种选择,它只是隐藏了进程,开发人员不需要创建明确的数组对象。

          所以您的 List&lt;String&gt; ... 可变参数实际上是 List&lt;String&gt;[] 并且与泛型不同,数组支持所有这些:-

             Parent[] par = new child[];
             Object[] objArray = new xyz[];
          

          在你的情况下:- 对象[] o = lst = List&lt;String&gt;[] = List&lt;String&gt; ...

          更多详情javadocs

          【讨论】:

            猜你喜欢
            • 2018-09-22
            • 2014-01-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-19
            • 2020-11-27
            • 2016-12-27
            • 2020-10-21
            相关资源
            最近更新 更多