【问题标题】:Java Pass Array of ArgumentsJava 传递参数数组
【发布时间】:2018-07-26 18:54:00
【问题描述】:

如何传递参数数组,例如 python 的f(*args)

其他语言的示例:

Python:f(*args)

JavaScript:f.apply(this, args)

鲁比:f(*args)

类似于Can I pass an array as arguments to a method with variable arguments in Java?varargs and the '...' argument,但函数声明不使用扩展语法。

void draw(int x, int y) {
    ...
}

另外,当参数不都是同一类型时,这是否可能?

void draw(int x, String y) {
    ...
}

【问题讨论】:

  • 任何东西——比如说一个由两个数字组成的数组,其中函数接受两个 int 参数
  • 已经在描述中指出这个问题有什么不同。
  • 不理解反对意见。完全准确的问题。如果您投反对票,请解释原因。
  • @GergelyBacso 已经在描述中指出这个问题有何不同。

标签: java arrays function methods


【解决方案1】:

您可以使用反射来做到这一点,但使用您初始化一次的缓存方法句柄可能更高效,然后根据需要多次重复使用。

class SpreadInvoker {
    public static void draw1(int x, String y) {
        System.out.printf("draw1(%s, %s)%n", x, y);
    }

    public void draw2(int x, int y) {
        System.out.printf("draw2(%s, %s)%n", x, y);
    }

    static MethodHandle DRAW1;
    static MethodHandle DRAW2;

    public static void main(String[] args) throws Throwable {
        DRAW1 = MethodHandles.lookup()
                             .findStatic(
                                 SpreadInvoker.class,
                                 "draw1",
                                 MethodType.methodType(
                                     void.class,
                                     int.class,
                                     String.class
                                 )
                             )
                             .asSpreader(Object[].class, 2);

        DRAW2 = MethodHandles.lookup()
                             .findVirtual(
                                 SpreadInvoker.class,
                                 "draw2",
                                 MethodType.methodType(
                                     void.class,
                                     int.class,
                                     int.class
                                 )
                             ).asSpreader(Object[].class, 2);

        SpreadInvoker instance = new SpreadInvoker();

        final Object[] args1 = { 13, "twenty-six" };
        final Object[] args2 = { 13, 26 };

        DRAW1.invoke(args1);           // SpreadInvoker.draw1(13, "twenty-six")
        DRAW2.invoke(instance, args2); // instance.draw2(13, 26)
    }
}

输出:

draw1(13, 二十六)
绘制2(13, 26)

但是请注意,如果您不知道在编译时需要调用什么方法,那么您会这样做。这种事情几乎是没有必要的。

【讨论】:

  • 是的,即使经过 10 年以上的 Java 学习,总有一些东西要学 :)
【解决方案2】:

这种调用方法的方式在 Java 语言中并不常见,但可以通过反射 API:

    Method drawMethod = YourClass.class.getDeclaredMethod("draw", new Class[] { int.class, int.class });
    drawMethod.invoke(null, (Object[]) args);

Further reading

【讨论】:

  • null 仅当方法被声明为静态时才符合invoke 的第一个参数
  • 谢谢!当参数不都是相同类型时,这将如何实现?
  • 您应该将所需的参数类型作为第二个参数传递给getDeclaredMethod。显然,这只有在实际声明了相应的方法时才有效。
  • 哦,太好了!因为 Object[] 可以包含任何东西?
  • invoke 的第二个参数的预期类型是 Object[]。在那里投射只是为了清楚起见。
【解决方案3】:

在java中很相似,但都必须是同一类型:

Java:f(String... args);

它调用“Varargs”,因此您可以通过这个世界搜索更多信息

【讨论】:

  • 谢谢!当函数没有使用特殊语法声明时,这是否有效?
  • 我说,当函数没有使用特殊语法声明时,这是否有效? IE。您如何称呼问题陈述中给出的示例?
  • 我不确定您在“特殊语法”下的意思。如果您的意思是您可以将参数作为变量而不像在 JavaScript 中那样声明它 - 那么不。
  • 关于调用 - 是的,您不需要“特殊”语法。即您可以将其称为 f("A"); f("A", "B", "C")
  • 知道了,所以给定 Java 中的普通方法,不可能像 Python 中那样传递参数数组?
【解决方案4】:

要传递未知数量的变量,您会这样做:

public void getNumber(int...args){
      ...
}

要找回你会做的:

args[0], args[1], args[2], ...

【讨论】:

    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    相关资源
    最近更新 更多