在Java中是否有办法创建一种方法返回 另一种方法的参数列表,以便我能够调用
anotherMethod(method())
其中anotherMethod
有任意参数,如
public void anotherMethod(int a, int b, String c)
如果类型保持不变,那将是什么,例如
public int add(int a, int b, int c)
如果没有这种方法,我怎么能建立参数列表以使其起作用?它是List
还是数组还是其他什么?
答案 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
...
请注意三个特殊情况null
,int[]
和为空。
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());
除此之外,如果您不想使用 varargs 或数组,则可以使用Collection
s(documentation) 。集合可以是List
或Set
,依此类推。例如,您可以声明
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>
甚至会更灵活。
使用Stream
(documentation)也可以像魅力一样工作,可能是最灵活的变种之一,因为流的来源可能是任何东西,几乎任何标准库都支持流表示。
现在请注意,您在开头搜索的内容是一种能够提供任意参数的方法,这在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());
}
}