【问题标题】:Can a method with arbitrary number of arguments, be called with an array?可以用数组调用具有任意数量参数的方法吗?
【发布时间】:2016-07-02 02:36:26
【问题描述】:

我想调用一个签名为的方法

public void foo(Object object, Object ... objects) { }

我这样称呼它

Object[] objects = ...;
foo(objects);

因为编译器没有抱怨它似乎是有效的,但是 签名中的第一个参数会发生什么?是objects[0]

谁能解释Object ... objects参数,内部发生了什么?

我无法更改方法,它来自 Method 类。

【问题讨论】:

    标签: java methods parameters call


    【解决方案1】:

    可变参数实际上是描述数组的不同语法,所以原则上是的。但是由于您明确定义了第一个参数,因此您必须单独传递它。

    vargs 的问题是您也无法传递任何参数,即长度为 0 的数组。这可能就是您要显式声明第一个参数的原因,这在 IMO 中是可以的。你就是不能随心所欲地称呼它。

    使用您的方法签名,以下应该可以工作:

    foo("first");
    foo("first", "second", "third");
    foo("first", new String[]{"second", "third"} );
    

    你的定义的问题,即使用Object 是数组也是对象,所以你上面描述的调用基本上就像foo("first")

    编辑

    由于您提到的方法是Method.invoke(Object object, Object ... objects),所以很明显为什么有2个参数。第一个是执行的目标,即应该调用该方法的实例,而第二个是参数数组。

    可以将该签名重写为Method.invoke(Object object, Object[] objects),但在不首先创建数组(即使长度为 0)的情况下调用它会更尴尬,或者您需要另一种只接受一个参数的方法才能调用无参数方法.

    【讨论】:

    • 我该如何称呼它?
    • 这不是我的定义,它来自 Method.invoke(Object object, Object ... objects)
    • @jam 我明白了,在这种情况下,两个参数都有不同的含义,即第一个是调用该方法的对象,可变参数是可选参数(可能没有)。在这种情况下,您应该将数组分开,因为方法执行的目标与参数不同。
    • 好吧,我误解了方法,我以为方法知道它是调用者
    • @jam 不,该方法属于一个类,如果它不是静态的,它将被传递给它在被调用时要操作的实例。在编译后的代码中,编译器会为您处理(将 this 添加到参数列表中),而在使用反射时,您必须提供实际实例(或 null 在静态方法的情况下)。
    【解决方案2】:

    我的猜测是您只会在其中获取一个参数。第二个Object... 参数基本上是可选的,因为空的Array 也是Array

    您方法中的第一个参数是Object 类型,这意味着您可以传递任何内容,包括ArrayObjects

    另外,Object... 在内部变成了Object[] 参数,它只是语法糖

    【讨论】:

      【解决方案3】:

      这里有一个小例子可以帮助你理解这里发生了什么:

      -> void foo(Object object, Object ... objects) {
      >>     System.out.println("First parameter: " + object);
      >>     System.out.println("Second parameter: " + Arrays.toString(objects));
      >> }
      >>
      |  Added method foo(Object,Object ...)
      -> Object[] objects = new Object[]{"test1", "test2", "test3"}
      |  Added variable objects of type Object[] with initial value [Ljava.lang.Object;@ae45eb6
      >>
      -> foo(objects)
      First parameter: [Ljava.lang.Object;@ae45eb6
      Second parameter: []
      

      如您所见,由于数组是对象,第一个参数将获取整个数组,而第二个参数将获取一个零大小的数组。为什么是空数组?因为 varargs 表示 个或多个对象,由于整个数组被分配给第一个参数,所以第二个参数获取“零”对象。

      【讨论】:

        【解决方案4】:

        这里,在你的情况下,

        objects-array 分配给 foo() 的第一个参数,即:Object object

        第二个参数“Object ... objects”指的是零大小 数组,

        所以,参考这个不带输出的例子可能会帮助你更好 方式,

          public static void main(String[] a) {
              Object[] objects = {
                      new Object() , new Object(), new Object()
              };
              foo(objects);
          }
        
          public static void foo(Object object, Object ... objects){
              System.out.println(object.hashCode());
        
              System.out.println("--------------");
              System.out.println(objects.length);
               for(Object o : objects){
                  System.out.println(o.hashCode());
              }
        
          }
        

        输出:

        848123013
        --------------
        0
        

        【讨论】:

          猜你喜欢
          • 2016-05-13
          • 1970-01-01
          • 2020-06-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-30
          • 2011-08-21
          • 2016-11-16
          相关资源
          最近更新 更多