Java函数式接口和Lambda表达式

huangapple go评论67阅读模式
英文:

Java Functional Interfaces and Lambda Expressions

问题

给定以下代码,请有人解释为什么断言返回 true?尽管我已经不停地搜索,但仍然找不到任何合适的答案,解释为什么会出现这种情况,以及导致这种行为的 Java 特性以及在类似创建这样的接口时需要满足什么限制/要求。

interface X {
  default int foo() {return 1;}
  String bar();
}

public class Exercise {
  public static void main(String[] arg) {
    X foo1 = () -> "hello";
    assert (foo1.bar()).equals("hello");
  }
}

请注意,以下是代码部分,不要翻译:

interface X {
  default int foo() {return 1;}
  String bar();
}

public class Exercise {
  public static void main(String[] arg) {
    X foo1 = () -> "hello";
    assert (foo1.bar()).equals("hello");
  }
}
英文:

Given the following code, can someone please explain why the assertion returns true? Despite having searched around countlessly, I haven't been able to get any appropriate answer for why this might be the case, and what the Java feature(s) cause this behaviour and what restrictions / requirements I would have in similarly creating an interface such as this.

interface X {
  default int foo() {return 1;}
  String bar();
}

public class Exercise{
  public static void main(String[]arg){
    X foo1=()->"hello";
    assert (foo1.bar()).equals("hello");
  }
}

答案1

得分: 13

一个lambda表达式是创建一个_函数式接口_实例的简洁方式,函数式接口是一个具有一个抽象方法的接口。在这里,X是一个函数式接口,具有抽象方法bar()。您可以使用以下方式来实现X:

class XImpl implements X { 
    public String bar() { return "Foo"; }
}

X instance = new XImpl();

或者使用匿名类:

X anon = new X() { 
    public String bar() { return "foo"; }
};

或者使用lambda表达式:

X lambda = () -> "foo";

这些方式都可以实例化X的实现。可能让您感到困惑的是lambda表达式的简洁性;因为X只有一个抽象方法bar,您不必声明正在实现bar - 编译器会自动推断。由于bar()不接受任何参数并返回String,编译器确保lambda的形状与唯一抽象方法的形状兼容。

因为X有一个bar()方法,
您可以在这些实例上调用它:

String s1 = instance.bar();
assertEquals(s1, "hello");

String s2 = anon.bar();
assertEquals(s2, "hello");

String s3 = lambda.bar();
assertEquals(s3, "hello");

对于每个实例,您都会得到相同的结果。

英文:

A lambda expression is a concise way to create an instance of a functional interface, which is an interface with one abstract method. Here, X is a functional interface, with abstract method bar(). You could implement X with:

class XImpl implements X { 
    public String bar() { return "Foo"; }
}

X instance = new XImpl();

or an anonymous class

X anon = new X() { 
    public String bar() { return "foo"; }
};

or a lambda

X lambda = () -> "foo";

Each of these instantiates an implementation of X. What may be confusing you is the concision of the lambda; because X has only one abstract method, bar, you don't have to say you are implementing bar -- the compiler figures it out. Since bar() takes no arguments and returns String, the compiler ensures that the shape of the lambda is compatible with the shape of the sole abstract method.

Because an X has a bar() method,
you can call it on each of these instances:

String s1 = instance.bar();
assertEquals(s1, "hello");

String s2 = anon.bar();
assertEquals(s2, "hello");

String s3 = lambda.bar();
assertEquals(s3, "hello");

and you get the same result for each.

答案2

得分: 4

由于方法 foo() 有默认实现,您只需要指定 bar() - 您可以使用 X foo1 = () -> "hello" 来实现。

因此,您的 foo1.bar() 返回 hello。

更新: 我的回答可能不够清楚,所以我应该注意,编译器不将 'foo' 视为抽象方法(这允许您的接口 X 满足声明函数式接口的要求)。Brian 在他的回答中更清晰和更详细地解释了这一点。

英文:

Since method foo() has default implementation, you only need to specify bar() - which you do with X foo1 = ()->"hello".

So, your foo1.bar() returns hello.

UPD: My answer may be unclear, so I should note that 'foo' is not treated as an abstract method by compiler (that lets your interface X satisfy the requirements of declaring functional interface). Brian explains it clearer and more detailed in his answer.

huangapple
  • 本文由 发表于 2020年7月22日 21:20:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63035160.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定