英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论