带有Iterable的方法签名中的省略行为(...)?

时间:2013-05-07 05:18:26

标签: java

假设我有一个方法(在库中,所以我无法修改它),如下所示:

public void ellipsisArg(Object...objects){
    for(Object object : objects){
        doSomething(object);
    }
}

如果我将Collection或Iterable传递给此方法,会发生什么? for()循环会遍历集合,还是会将Collection作为一个对象接受并将整个事件传递给doSomething()?

2 个答案:

答案 0 :(得分:5)

I tested it in Ideone (using Java6):

import java.util.*;
import java.lang.*; 

class Main{

    public static void main (String[] args) throws java.lang.Exception{
        testIterable(getStringList());     
    }

    public static ArrayList<String> getStringList(){
        ArrayList<String> stringList = new ArrayList<String>();

        stringList.add("String one");
        stringList.add("String two");

        return stringList;       

    }

    public static void testIterable(Object...objects){
        for(Object object : objects){
            System.out.println("Object: "+ object.toString());
        }
    }
}

预期输出为:

  

对象:字符串一

     

对象:字符串二

不幸的是,输出结果如下:

  

对象:[String one,String two]

因此它将整个ArrayList作为一个Object。

修改

但是,将ArrayList转换为String []会产生所需的行为,这是一项简单的任务:

public static String[] convertToArray(ArrayList<String> stringList){
    String[] stringArray = new String[stringList.size()];
    // If we use toArray() without an argument, it will return Object[]
    return stringList.toArray(stringArray);
}

Ideone link

答案 1 :(得分:0)

语义是:

  • 如果只有一个参数且其类型为Object[]或子类,则它将保持不变
  • 如果所有参数类型都是Object或子类,则会创建并传递Object[]数组。

Collection不是Object[]的子类,因此它将作为新创建的Object[]的单个成员传递。

另请注意,这是在编译时解决的,因此如果您使用Object实例传递Object[]变量,它将被包装到另一个数组。例如:

Object o = new Object[0];
ellipsisArg(o);
Object[] o2 = new Object[0];
ellipsisArg(o2);

ellipsisArg方法仅获得o2的预期数据。