数组包含 Methods/Functions 用于参数传递

Array Containing Methods/Functions for Argument Passing

我有一个方法 select 介于数组的参数和 return 特定的参数之间。例如,这是该方法:

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 不带参数且 return void)

但这会引发编译器错误:

incompatible types: invalid method reference but expected no arguments.
    found: java.lang.Void
    reason: actual and formal argument lists differ in length

我一直在玩 lambda,例如:

() -> ClassA.method1()

但我无法让它工作。有谁知道我做错了什么并且知道解决这个问题的方法吗?

编辑: 我在 Stack Overflow 上看过 this,但这是针对 C# 的,我还没有想出如何在 Java.

中模仿它

示例:
假设我有一个 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--;
    }
}

最后我有一个 Main class。在 action 方法中(在 Main class 中)我想要一个包含这两个方法的数组,以便在 [=20= 时在它们之间 select ](如下所示)是 listentext:

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 是一种采用一个参数并且 return 是一个结果的方法。您使用的方法不带任何参数且不产生 return 结果。你不能为此使用 Function(使用 Void 不是解决这个问题的方法),但是 the java.util.function 包包含许多 classes 用于不同的常见组合(不带参数但 return 结果的方法,带一个或两个参数但不 return 结果的方法,带原始参数或 return 原始结果的方法赢了不能在 Function 中工作,因为类型不是 class 类型,等等)。

java.util.function中没有class没有参数也没有结果的功能接口,但是Runnable可以用于那个。

您需要确保使用正确的界面。

注意: 我假设 method1method2 是静态方法,因此它们不接受任何参数,即使是隐藏的 "instance" 实例方法采用的参数。如果它们是实例方法,那么事情必须以不同的方式完成。

既然您已经阐明了它们是实例方法,事情就不同了——但这取决于您如何获得该方法。如果你说

Word::incListenCorrect

由于您使用的是 class 名称,因此您需要提供实例作为参数。因此,Word::incListenCorrect return 是一个函数式接口,用于接受一个参数的方法,例如 Consumer<Word>,并且您必须在调用该方法时将 Word 作为参数传递.accept()但是:

word::incListenCorrect

非常不同。现在,word 实例变成了 "baked into" 方法引用,所以它不需要作为参数传递。因此,在这种情况下,您仍然需要不带参数且不 return 值的接口,即 Runnable。当你说

Runnable r = word::incListenCorrect;    
r.run();

其中 rRunnable,它将自动使用 word 作为实例方法的实例,因为 word 成为 r 的一部分当您将方法引用分配给它时。