当前位置: 首页 > 知识库问答 >
问题:

Java扩展运算符

萧英光
2023-03-14

我不确定我在这里使用的词汇,如果我错了,请纠正我。

在Javascript中,我有以下代码:

let args = [1,2,3];

function doSomething (a, b, c) {
    return a + b + c;
}

doSomething(...args);

如您所见,当调用doSomething时,我可以使用spread运算符,以便将我的参数“转换”为1、2、3

现在,我正试图用Java做同样的事情。

假设我有一门Foo课:

public class Foo {
    public int doSomething (int a, int b, int c) {
        return a + b + c;
    }
}

现在我想调用doSomething

int[] args = {1, 2, 3};

我想使用类似于do某物(... args)的东西,而不是调用do某物(args[0],args[1],args[2])

我在函数声明中看到了这一点,但我不想改变这样一个函数的实现。

共有3个答案

吴靖
2023-03-14

Java语言不提供操作员来执行此操作,但它的类库有一个工具来执行您需要的操作。

[来自OP的评论]Foo的开发者可以自己选择函数doSomething需要的参数数量。然后,我将能够构造一个参数“包”,并将其注入方法中。

使用反射API,这就是它的用途。它要求您将参数打包到一个数组中。需要做很多额外的工作,包括包装/展开单个方法参数和方法结果,但您可以在运行时检查签名、构造数组并调用该方法。

class Test {
    public static int doSomething(int a, int b, int c) {
        return a + b + c;
    }
    // This variable holds method reference to doSomething
    private static Method doSomethingMethod;
    // We initialize this variable in a static initialization block
    static {
        try {
            doSomethingMethod = Test.class.getMethod("doSomething", Integer.TYPE, Integer.TYPE, Integer.TYPE);
        } catch (Exception e) {
        }
    }
    public static void main (String[] ignore) throws java.lang.Exception {
        // Note that args is Object[], not int[]
        Object[] args = new Object[] {1, 2, 3};
        // Result is also Object, not int
        Object res = doSomethingMethod.invoke(null, args);
        System.out.println(res);
    }
}

上面的代码打印6(演示)。

屠兴旺
2023-03-14

实际上,由于兼容性的原因,使用varargs函数(Object... args)的方法的签名等同于使用数组函数(Object[]args)声明的方法。

因此,为了将任何集合传递并传播到需要varargs的函数,需要将其转换为数组:

import java.util.Arrays;
import java.util.stream.Stream;

public class MyClass {
  
  static void printMany(String ...elements) {
     Arrays.stream(elements).forEach(System.out::println);
  }
  
  public static void main(String[] args) {
    printMany("one", "two", "three");
    printMany(new String[]{"one", "two", "three"});
    printMany(Stream.of("one", "two", "three").toArray(String[]::new));
    printMany(Arrays.asList("foo", "bar", "baz").toArray(new String[3]));
  }
}

所有这些调用printMany都将打印:

它与spread操作符并不完全相同,但在大多数情况下,它已经足够好了。

邵宜年
2023-03-14

在java中有一个可变参数的概念,使用它你可以将不同数量的参数传递给同一个函数

我以您的代码为例:

public class Foo {
    public int doSomething (int ...a) {
      int sum = 0;
      for (int i : a)
           sum += i;
        return sum;
    }
 }

现在可以将此函数称为:

doSomething (args)

有关更多信息,请访问以下链接:http://www.geeksforgeeks.org/variable-arguments-varargs-in-java/

 类似资料:
  • 为什么一定要使用 ...path 才能正确的运行,在上面代码中测试的结果是一样的,而下面则一定要用 ... ?否则就会出现如图2所示的结果 这段代码是 解决 (给定两个整数 n 和 k,返回范围 [1,n] 中所有可能的 k 个数的组合。) 这个问题的 ,用的回溯

  • 问题内容: 我有能力在编译时扩展一个类,但是我需要能够在运行时使用已实例化的超类的实例创建此子类的实例。 从理论上讲这应该是可能的,因为已经在子类构造函数之前调用了超类构造函数。 我没有足够的程序访问权限来更改实例化到我的子类或中断原始实例化。 用例:现有一个类X实例的数组。我的代码在之后加载。我需要使用已加载的子类Y扩展X来覆盖实例X之一的方法之一。父程序仅通过该数组访问对象,因此我想用Y实例替

  • 本文向大家介绍ES6扩展运算符和rest运算符用法实例分析,包括了ES6扩展运算符和rest运算符用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了ES6扩展运算符和rest运算符用法。分享给大家供大家参考,具体如下: 运算符可以很好的为我们解决参数和对象数组未知情况下的编程,让我们的代码更健壮和简洁。 运算符有两种:对象扩展运算符与rest运算符。 1.对象扩展( spread

  • 我有一个函数可以给传入的对象添加一个键,但是我被告知要使用spread运算符,我被告知可以使用spread运算符创建一个具有相同属性的新对象,然后在它上面设置isAvailable。 所以我试过这样的方法,但是不能成功,你能帮我吗?和困惑,我应该这样使用spread运算符,从一个函数返回?

  • 问题内容: 我想扩展ArrayList,为特定类添加一些方法,这些类的实例将由扩展的ArrayList保存。下面是一个简化的说明性代码示例。 这对我来说似乎是明智的,但是我对Java还是很陌生,我看到了其他阻碍扩展ArrayList的问题,例如,扩展ArrayList和创建新方法。我对Java的理解不够了解。 在我先前的尝试中,我最终在ThingContainer中创建了许多实际上是传递给Arra

  • 算术扩展提供了一种强力的工具, 可以在脚本中执行(整型)算法操作. 可以使用backticks, double parentheses, 或 let来将字符串转换为数字表达式. 一些变化 使用反引号的算术扩展(通常都是和expr一起使用) 1 z=`expr $z + 3` # 'expr'命令将会执行这个扩展. 使用双括号, 和let形式的算术扩展 反引号形式的算术扩展已