我有一个方法可以在数组的参数之间进行选择并返回一个特定的参数。例如,这是方法:
private <T> T selectOnType(T[] selection, T defaultOp){
switch(this.type){
case Resources.TEXT:
return selection[Resources.TEXT];
case Resources.LISTEN:
return selection[Resources.LISTEN];
default:
return defaultOp;
}
}
如何构造一个充满方法引用的数组(即函数指针),以便能够将该数组传递给上面的方法?
我尝试过这样的事情:
java.util.function.Function<Void, Void>[] array = {ClassA::method1, ClassA::method2};
(其中method1和method1不带参数并返回void)
但是这会引发编译错误:
不兼容的类型:无效的方法引用但预期没有参数。
找到:java.lang.Void
原因:实际和正式的参数列表长度不同
我一直在玩lambdas,例如:
() -> ClassA.method1()
但我无法让它发挥作用。有谁知道我做错了什么,知道解决这个问题的方法吗?
编辑: 我在 Stack Overflow 上看过this,但这是针对C#的,我还没弄清楚如何用Java模仿它。
示例:
假设我有一个Word
类:
public class Word{
private final String text;
private int listenCorrect = 0, textCorrect = 0;
public Word(final String test){
this.text = text;
}
public void incListenCorrect(){
listenCorrect++;
}
public void incTextCorrect(){
textCorrect--;
}
}
最后我有一个Main
课程。在action
方法内(在Main
类中)我希望在其中包含一个包含这两个方法的数组,以便在type
(如下所示)为{listen
之间进行选择{1}}或text
:
public class Main{
int type = 0;
public void action(){
Word word = new Word("Hello");
// 'Functions' is used to represent something I tried above (just for demonstration)
Function[] array = {word::incListenCorrect, word::incTextCorrect};
Function picked = selectOnType(array, word::incTextCorrect);
picked.call();
}
/*
* Resources is another class that contains the following values:
* public static final int TEXT = 0;
* public static final int LISTEN = 1;
*/
private <T> T selectOnType(T[] selection, T defaultOp){
switch(this.type){
case Resources.TEXT:
return selection[Resources.TEXT];
case Resources.LISTEN:
return selection[Resources.LISTEN];
default:
return defaultOp;
}
}
}
答案 0 :(得分:3)
Function
是一个接受一个参数并返回结果的方法。您正在使用不带参数且不返回结果的方法。您不能Function
使用Void
(使用Function
方式来解决此问题),但the java.util.function
包中包含许多针对不同常见组合的类(不带参数但返回结果的方法,带有一个或两个参数但不返回结果的方法,采用原始参数的方法或返回不能在java.util.function
中工作的原始结果因为类型不是类类型等。
Runnable
中的类没有参数且没有结果的功能接口,但method1
可用于此。
您需要确保使用正确的界面。
注意:我假设method2
和Word::incListenCorrect
是静态方法,因此他们不会接受任何参数,即使是隐藏的&#34;实例& #34;实例方法采用的参数。如果他们是实例方法,则必须采取不同的方式。
现在您已经澄清了他们的实例方法,但情况有所不同 - 但这取决于您如何获得该方法。如果你说
Word::incListenCorrect
因为您正在使用类名,所以您需要提供实例作为参数。因此,Consumer<Word>
返回一个带有一个参数的方法的函数接口,例如Word
,当您使用{{1}调用方法时,必须传递.accept()
作为参数}}。 但是:
word::incListenCorrect
非常不同。现在,word
实例变为&#34;烘焙到&#34;方法引用,因此它不需要作为参数传递。因此,在这种情况下,您仍然需要不带参数的接口,并且不返回值Runnable
。当你说
Runnable r = word::incListenCorrect;
r.run();
其中r
是Runnable
,它会自动使用word
作为实例方法的实例,因为当您word
成为r
的一部分时为它分配了方法参考。