Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中的运行时确定的实例上使用方法引用_Java_Java 8_Method Reference - Fatal编程技术网

在Java中的运行时确定的实例上使用方法引用

在Java中的运行时确定的实例上使用方法引用,java,java-8,method-reference,Java,Java 8,Method Reference,我正在测试使用方法引用的规则,但我编写的代码无法编译。编译器一直告诉我不能从静态上下文引用非静态方法。然而,在Java文档中,它明确指出可以使用“:”to“引用特定类型的任意对象的实例方法”。有人能指出我的代码有什么问题吗?谢谢大家! package Test; import java.util.function.BiPredicate; class Evaluation { public boolean evaluate(int a, int b) { if (a-b

我正在测试使用方法引用的规则,但我编写的代码无法编译。编译器一直告诉我不能从静态上下文引用非静态方法。然而,在Java文档中,它明确指出可以使用“:”to“引用特定类型的任意对象的实例方法”。有人能指出我的代码有什么问题吗?谢谢大家!

package Test;
import java.util.function.BiPredicate;

class Evaluation {
    public boolean evaluate(int a, int b) {
        if (a-b ==5){
            return true ;
        }
        return false; 
    }

    public void methodTest() {
        BiPredicate<Integer, Integer> biPredicate = Evaluation::evaluate;
        System.out.println(biPredicate.test(6,1));
    }
}
封装测试;
导入java.util.function.BiPredicate;
课堂评价{
公共布尔求值(int a,int b){
如果(a-b==5){
返回true;
}
返回false;
}
公共无效方法测试(){
BiPredicate BiPredicate=评估::评估;
系统输出打印LN(双预测测试(6,1));
}
}
编辑:在阅读了答案之后,我想知道是否通过类名引用实例方法只在某些函数接口中有效,而在其他接口中无效?比如说,

BiPredicate <String, Integer> biPredicate =  String::startsWith;
BiPredicate BiPredicate=String::startsWith;
不编译,而:

Predicate <String> predicate = String::isEmpty;
谓词=字符串::isEmpty;
编译。
如果是这种情况,是否有一个页面/教程/任何人可以向我介绍的内容,解释哪些功能接口兼容,哪些不兼容

如果您的方法是实例方法,则必须在某个实例上调用它,例如:

public void methodTest(){
    BiPredicate<Integer, Integer> biPredicate = this::evaluate;
    System.out.println(biPredicate.test(6,1));
}
public-void-methodTest(){
BiPredicate BiPredicate=this::evaluate;
系统输出打印LN(双预测测试(6,1));
}

由于您没有使用任何实例变量或方法,因此可以简单地将其设置为静态并保持不变。

静态引用实例方法时,返回的函子将使用表示实例的附加参数

interface Func {
    boolean evaluate(Evaluation instance, int a, int b);
}
...
Func biPredicate = Evaluation::evaluate;
System.out.println(biPredicate.evaluate(new Evaluation(), 6, 1));
但是在调用它时,需要传递
求值
的实例


由于您的
evaluate
方法不使用任何实例字段,您不妨将其设置为
静态
,这样您就不需要传递实例,只需像您尝试的那样使用
BiPredicate

我仍在尝试找出适用的规则,但如果您使用

BiPredicate<Integer, Integer> biPredicate = this::evaluate;
BiPredicate BiPredicate=this::evaluate;
我一直在费解,但尽可能接近我所能,因为
Evaluation::evaluate
强制编译器创建一个类型为
Evaluation
的任意对象,并且您从该类型的对象中调用它,规则是不同的。您需要从出现
methodTest
方法的特定对象调用它

虽然我没有解释,但解决方案是使用
this::evaluate
。它明确地将方法引用绑定到调用它的对象


旁注:从
布尔值
导出
布尔值
时,不需要将
布尔值作为条件求值。您可以
返回a-b==5

我回答这个问题可能太迟了,但由于这个问题仍然没有答案,我想尝试一个答案

我认为OP试图实现的目标有一个缺陷

我理解OP试图理解,为什么这样的事情会起作用:

    String str = "abc";
    Predicate<String> methodRef = str::startsWith; 
    methodRef.test("s");
String str=“abc”;
谓词methodRef=str::startsWith;
方法参考试验(“s”);
然后呢,

Predicate <String> predicate = String::isEmpty 
谓词=字符串::isEmpty
以类似的方式工作,为什么不呢

Predicate <String> predicate =  String::startsWith;
谓词=字符串::startsWith;
采用字符串类名Compile的Compile

这仅仅是因为谓词基本上接受任何参数并返回布尔值。这不是解决此问题的正确设置

你可以试试

BiFunction<String, String, Boolean> methodRef2 = String::startsWith;
methodRef2.apply("sdsdfsd", "sdfsdf");
BiFunction methodRef2=String::startsWith;
方法参考2.应用(“SDFSD”、“sdfsdf”);
这是可行的,因为startswith需要一个源字符串,用于检查和返回值的字符串。在Java8中,基本上有4种方法可以调用方法引用

  • 静态方法调用
  • 实例方法调用
  • 类方法调用
  • 建设者

  • 我在写同样的答案;)由于该方法不使用实例变量/方法,所以我认为您的答案是错误的,OP应该简单地将方法
    改为static
    。或者,既然代码是在一个非静态方法中,为什么要创建一个新实例呢?使用
    this::evaluate
    @Andreas再试一次,我在那里输入了一个错误。这对我来说很好:)@Andreas这是一个不同的解决方案,但我想解释为什么OP的版本不起作用,以及如何使它起作用。我的建议是将该方法设置为静态。@Andreas我的代码显示了静态引用实例方法的实际工作原理,这是一个冗长的过程,因为在
    java.util.function
    中没有可以使用的标准接口。我打算发布这个。这表明您可以引用具有类名的实例方法,前提是您可以提供正确的函数接口。@Andreas:这个答案解决了OP的实际问题。
    newevaluation()
    的参数只是一个例子,因为OP没有提供参数。但是您可以在每次调用时传递不同的实例…另请参见
    String::startsWith
    将使用3个参数;1.要调用的
    字符串
    实例,2。
    字符串
    参数
    前缀
    和3。
    int
    参数
    toffset
    。但是,
    Bipredicate
    只能解释其中的两个
    String::isEmpty
    ,接受1个参数,即要调用的实例,因此
    谓词
    将起作用。@jornverne您完全正确。然而,为什么
    谓词=String::isEmpty工作?比如我为什么不需要传递一个新的
    String()
    (如下所示)实例