使用方法提供参数

时间:2017-12-04 23:28:05

标签: java arguments

在Java中是否有办法创建一种方法返回 另一种方法参数列表,以便我能够调用

anotherMethod(method())

其中anotherMethod有任意参数,如

public void anotherMethod(int a, int b, String c)

如果类型保持不变,那将是什么,例如

public int add(int a, int b, int c)

如果没有这种方法,我怎么能建立参数列表以使其起作用?它是List还是数组还是其他什么?

4 个答案:

答案 0 :(得分:2)

如果在呼叫站点修复了参数数量,您可以使用varargs

int add(int... numbers)

否则你会使用数组或集合

int add(int[] numbers)

当然,您可以使用另一种方法提供这些参数的值:

add(someOtherMethod())

答案 1 :(得分:1)

可变参数

Java有一个内置功能来表示可变长度的参数。它被称为 varargs documentation)(变量参数),只有在类型保持不变时才有效。方法的语法如下:

public int add(int... values)

请注意int... values表示 varargs 。调用者现在可以调用类似

的方法
add(null)        // Passing null
add(values)      // Passing an int[]
add()            // No arguments
add(a)           // One int
add(a, b)        // Two ints
add(a, b, c)     // Three ints
add(a, b, c, d)  // Four ints
...

请注意三个特殊情况nullint[]为空

Java的作用是将参数转换为数组。因此,方法values内部将是常规int[]。因此,您可以实现像

这样的方法
public int add(int... values) {
    int sum = 0;
    for (int value : values) {
        sum += value;
    }
    return sum;
}

如果您作为调用方想要传递function的返回值,则只需确保它返回数组,如int[]。所以以下方法可行:

public int[] valueProvider() {
    int[] values = ...

    return values;
}

然后将其称为

int sum = add(valueProvider());

收集,Iterable和Stream

除此之外,如果您不想使用 varargs 数组,则可以使用Collection s(documentation) 。集合可以是ListSet,依此类推。例如,您可以声明

public int add(Collection<Integer> values)

并像

一样喂它
Collection<Integer> values = new ArrayList<>();
values.add(1);
values.add(2);
int sum = add(values);

Iterable<Integer>相比,Collection<Integer>甚至会更灵活。

使用Streamdocumentation)也可以像魅力一样工作,可能是最灵活的变种之一,因为流的来源可能是任何东西,几乎任何标准库都支持流表示。

更改类型

现在请注意,您在开头搜索的内容是一种能够提供任意参数的方法,这在Java中是不可能的。

主要问题是类型可能会改变,因此您可能有类似

的方法
public void doSomething(int first, String second, File third)

并且您无法使用varargs,Collections或任何提供的方法来提供方法。

在这种情况下,您需要包装类,如

public class DoSomethingArguments {
    private int mFirst;
    private String mSecond;
    private File mThird;

    public DoSomethingArguments(int first; String second, File third) {
        this.mFirst = first;
        this.mSecond = second;
        this.mThird = third;
    }

    // Some getters
}

(或通用的元组类,在这种情况下为三元组)

但是,您需要将方法更改为

public void doSomething(DoSomethingArguments arguments)

可能不是您想要的,因为您可能打算不更改doSomething的签名

但不幸的是,没办法以这种方式提供这样的方法。

答案 2 :(得分:1)

编译时,没有任何方法符合您的要求。正如其他答案所指出的那样,有 varargs 。但这只是语法糖。这只是编译器隐式为您创建某种类型的数组。

但除此之外,还有 reflection 。 Reflection允许您在* runtime。

动态检查类和方法

换句话说:你可以做类似

的事情
Object whatever = ...
Class<?> someClass = whatever.getClass();

现在你可以问someClass它有哪些方法。他们需要哪些参数。

但是如上所述:所有这些只是运行时。反思API很容易出错。而且你只能在运行时发现一些异常被抛出。

答案 3 :(得分:0)

没有直接的方式以您想要的方式传递多个值。但是您可以使用间接方式传递一组不同类型的值。我可以想到两种方式,但它们可以更多。

Firs - 使用地图,只需插入要在集合中传递的值,然后将集合传递给第二个方法。

第二 - 创建一个bean(Java POJO)作为参数传递给使用方法。

一个小样本代码。

 class Sample{
    private int a;
    private String b;
    private int c;

    Sample(int a,String b,int c){
        this.a = a;
        this.b = b;
        this.c = c;
    }
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public String getB() {
        return b;
    }
    public void setB(String b) {
        this.b = b;
    }
    public int getC() {
        return c;
    }
    public void setC(int c) {
        this.c = c;
    }
}
    public class PassingExample {
    public void consumerofInputs (Map<Integer, Object> input)/*(int a, String b, int c)*/{
        System.out.println("I use three different inputs : int, string and int");
        for (Map.Entry<Integer, Object> entry : input.entrySet()) {
            System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
        }

    }

    public Map producingInput() {
        Map<Integer, Object> input = new HashMap<Integer, Object>();
        input.put(1, 10);
        input.put(2, "input");
        input.put(3, 89);
        return input;
    }

    public Sample createClassAsInput(){
        Sample input = new Sample(10,"class-input",30);
        return input;

    }

    public void useSampleAsInput(Sample input){
        System.out.println("\nUsing Class as input \nInt::"+input.getA()+"\nString::"+input.getB()+"\nInt::"+input.getC());
    }

    public static void main(String[] args) {
        PassingExample example = new PassingExample();
        example.consumerofInputs(example.producingInput());
        example.useSampleAsInput(example.createClassAsInput());
    }
}