I have a method that selects between the arguments of an array and returns a specific one. For instance, here is that method:
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;
}
}
How can I construct an array full of method references (ie function pointers) in order to be able to pass that array into this method above?
I tried doing such things as:
java.util.function.Function<Void, Void>[] array = {ClassA::method1, ClassA::method2};
(where method1 and method1 take no arguments and return void)
But that throws a compiler error saying:
incompatible types: invalid method reference but expected no arguments.
found: java.lang.Void
reason: actual and formal argument lists differ in length
I have been playing around with lambdas such as:
() -> ClassA.method1()
But I haven't been able to get it to work. Does anyone know what I am doing wrong and know a solution to this problem?
EDIT: I have seen this on Stack Overflow , but this is for C# and I haven't figured out how to mimic it in Java.
Example:
Let's say I have a Word
class:
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--;
}
}
And finally I have a Main
class. Inside the action
method (in the Main
class) I want to have an array with these two methods in it in order to select between them if the type
(shown below) is either listen
or 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;
}
}
}
A Function
is a method that takes one argument and returns a result. You're using methods that take no arguments and do not return results. You can't use Function
for this (using Void
isn't a way to get around this), but the java.util.function
package contains a number of classes for different common combinations (methods that take no arguments but return a result, methods that take one or two arguments and don't return a result, methods that take primitive arguments or return primitive results that won't work in a Function
because the types aren't class types, etc.).
There isn't a class in java.util.function
for a functional interface with no arguments and no result, but Runnable
can be used for that.
You need to make sure you use the correct interface.
I was assuming method1
and method2
are static methods, so that they don't take any arguments, even a hidden "instance" argument that instance methods take. 我假设method1
和method2
是静态方法,因此它们不接受任何参数,甚至是实例方法所采用的隐藏“实例”参数。 If they're instance methods, then things have to be done differently.
Now that you've clarified that they're instance methods, things are different--but it depends on how you get the method. If you say
Word::incListenCorrect
since you're using the class name, you need to provide the instance as an argument. Therefore, Word::incListenCorrect
returns a functional interface for a method that takes one argument, such as Consumer<Word>
, and you have to pass the Word
as the argument when you call the method with .accept()
. But :
word::incListenCorrect
is very different. Now, the word
instance becomes "baked into" the method reference, so it doesn't need to be passed as an argument. In this case, therefore, you'll still need the interface that takes no arguments and does not return a value, which is Runnable
. When you say
Runnable r = word::incListenCorrect;
r.run();
where r
is a Runnable
, it will automatically use word
as the instance for the instance method, since word
became part of r
when you assigned the method reference to it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.