Java 8函数接口分配上下文

Java 8函数接口分配上下文,java,java-8,Java,Java 8,问题是关于功能接口的赋值上下文- Predicate<String> p = String::isEmpty; 做同样的任务- Predicate<String> p = Test::isEmpty; 谓词p=Test::isEmpty; 这将是一个编译错误- 类型测试没有定义适用的isEmpty(字符串) 这里 和谓词表示一个参数的谓词(布尔值函数),函数方法是布尔测试(T){} 有什么解释吗?我遗漏了什么吗?方法引用可以用几种方式使用。它可以捕获要在其上调用的实

问题是关于功能接口的赋值上下文-

Predicate<String> p = String::isEmpty;
做同样的任务-

Predicate<String> p = Test::isEmpty;
谓词p=Test::isEmpty;
这将是一个编译错误-

类型测试没有定义适用的isEmpty(字符串) 这里

谓词
表示一个参数的谓词(布尔值函数),函数方法是
布尔测试(T){}


有什么解释吗?我遗漏了什么吗?

方法引用可以用几种方式使用。它可以捕获要在其上调用的实例。它可以引用应该在函数接口(您的第一个示例)提供的参数上调用的方法。它还可以用作调用目标,其中函数接口中的参数作为参数传递给所引用方法的调用(第二个示例)

谓词
接受泛型类型参数的任何参数。您提供的方法引用必须能够对其执行某些操作。

您应该具有:

Predicate<Test> p = Test::isEmpty;
那么为什么要有
谓词

看。这里有第三种情况“引用特定类型的任意对象的实例方法”

拥有

Predicate<String> p = String::isEmpty();
String s = "";
谓词p=String::isEmpty();
字符串s=“”;
调用
p.test
与callign
s.isEmpty()相同字符串作为参数来调用
测试中的方法


如果
String
Test
都使用方法
boolean isEmpty()
实现接口
Empty
,然后使用
Predicate
,则可能会有一个公共的
谓词。然后
p.test(string)
p.test(test)
都可以工作;否则它不会,Java具有强类型,不支持duck类型。

当您使用
谓词时,则只接受
字符串的方法引用。
要给出
测试
类的方法引用,您需要
谓词

因此,守则应为:

Predicate<Test> p = Test::isEmpty;
谓词p=Test::isEmpty;
而不是

Predicate<String> p = Test::isEmpty;
谓词p=Test::isEmpty;
为了使我的观点更清楚,请考虑下面的代码:-< /P>
public static void main(String args[]){
    Predicate<String> p;
    p = String::isEmpty;
    Predicate<Test> q;
    q = Test::isEmpty;
}

interface Predicate<T>{
    public boolean test(T t);
}

class Test{
    public boolean isEmpty(){
        return true;
    }
}
publicstaticvoidmain(字符串参数[]){
谓语p;
p=String::isEmpty;
谓词q;
q=测试::i空;
}
接口谓词{
公共布尔检验(T);
}
课堂测试{
公共布尔值为空(){
返回true;
}
}

我想补充@m3th0dman的答案

您确实有一种方法可以使用
Test
类的方法引用定义
谓词。方法是将
isEmpty
方法定义为静态的,并具有
String
参数

public class Test
{

  public static boolean isEmpty (String s)
  {
    return s.length() == 0;
  }

  public static void main (String[] args)
  {
      Predicate<String> p = Test::isEmpty;
      System.out.println(p.test("ff"));
      System.out.println(p.test(""));
  }

}
公共类测试
{
公共静态布尔值isEmpty(字符串s)
{
返回s.length()==0;
}
公共静态void main(字符串[]args)
{
谓词p=Test::isEmpty;
系统输出打印(p.test(“ff”));
System.out.println(p.test(“”);
}
}

您能告诉我功能接口分配背后的编译逻辑吗。@sub它在JLS中。请看第二点。非常简单:类不是接口,所以它不能是函数接口。
Predicate<String> p = Test::isEmpty;
public static void main(String args[]){
    Predicate<String> p;
    p = String::isEmpty;
    Predicate<Test> q;
    q = Test::isEmpty;
}

interface Predicate<T>{
    public boolean test(T t);
}

class Test{
    public boolean isEmpty(){
        return true;
    }
}
public class Test
{

  public static boolean isEmpty (String s)
  {
    return s.length() == 0;
  }

  public static void main (String[] args)
  {
      Predicate<String> p = Test::isEmpty;
      System.out.println(p.test("ff"));
      System.out.println(p.test(""));
  }

}