lambda 可以访问其目标功能接口的成员吗?
Can a lambda access members of its target functional interface?
我使用 java8 创建了一个简单的界面。因为它包含一种方法和一种默认方法。
interface Lambda{
default void dummy(){
System.out.println("Call this..");
}
void yummy();
}
我正在尝试使用像
这样的历史方式来使用这两种方法
public class DefaultCheck {
public static void main(String[] args) {
DefaultCheck check = new DefaultCheck();
check.activate(new Lambda() {
@Override
public void yummy() {
dummy();
}
});
}
void activate(Lambda lambda){
lambda.yummy();
}
}
现在我正在尝试使用 lambda 表达式实现同样的事情,但出现类似“dummy is undefined”的错误
check.activate(() -> {
dummy();
});
任何人都可以提出建议,如何使用 Lambda 表达式实现这种情况??
内部 class 实现有效,因为调用代码就像您编码一样:
check.activate(new Lambda() {
@Override
public void yummy() {
this.dummy();
}
});
我们现在的问题是 lambda 没有引入新的作用域。因此,如果您希望您的 lambda 能够引用自身,您可以优化您的 @FunctionalInterface 以便其功能方法接受自身及其所需的参数:
check.activate(this_ -> this_.dummy());
其中 Lambda 定义为:
@FunctionalInterface
public interface Lambda {
void yummy(Lambda this_);
default void yummy() {
yummy(this);
}
default void dummy(){
System.out.println("Call this..");
}
}
做不到。
JLS 15.27.2 解决这个问题:
Unlike code appearing in anonymous class declarations, the meaning of
names and the this and super keywords appearing in a lambda body,
along with the accessibility of referenced declarations, are the same
as in the surrounding context (except that lambda parameters introduce
new names).
The transparency of this (both explicit and implicit) in the body of a
lambda expression - that is, treating it the same as in the
surrounding context - allows more flexibility for implementations, and
prevents the meaning of unqualified names in the body from being
dependent on overload resolution.
Practically speaking, it is unusual for a lambda expression to need to
talk about itself (either to call itself recursively or to invoke its
other methods), while it is more common to want to use names to refer
to things in the enclosing class that would otherwise be shadowed
(this, toString()). If it is necessary for a lambda expression to
refer to itself (as if via this), a method reference or an anonymous
inner class should be used instead.
如果我没理解错的话。您正在尝试通过 lambda 实现调用接口中的默认方法。我觉得可以。
@FunctionalInterface
interface Value
{
String init(Value a);
default String add(String b)
{
return "added content "+b;
}
default String getResult()
{
String c = init(this);
return c;
}
}
public class Main
{
public static void main(String[] args)
{
Value v = a -> a.add("inpout"); // here I am calling add method in Value interface.
String c = v.getResult();
System.out.println(c);
}
}
我使用 java8 创建了一个简单的界面。因为它包含一种方法和一种默认方法。
interface Lambda{
default void dummy(){
System.out.println("Call this..");
}
void yummy();
}
我正在尝试使用像
这样的历史方式来使用这两种方法public class DefaultCheck {
public static void main(String[] args) {
DefaultCheck check = new DefaultCheck();
check.activate(new Lambda() {
@Override
public void yummy() {
dummy();
}
});
}
void activate(Lambda lambda){
lambda.yummy();
}
}
现在我正在尝试使用 lambda 表达式实现同样的事情,但出现类似“dummy is undefined”的错误
check.activate(() -> {
dummy();
});
任何人都可以提出建议,如何使用 Lambda 表达式实现这种情况??
内部 class 实现有效,因为调用代码就像您编码一样:
check.activate(new Lambda() {
@Override
public void yummy() {
this.dummy();
}
});
我们现在的问题是 lambda 没有引入新的作用域。因此,如果您希望您的 lambda 能够引用自身,您可以优化您的 @FunctionalInterface 以便其功能方法接受自身及其所需的参数:
check.activate(this_ -> this_.dummy());
其中 Lambda 定义为:
@FunctionalInterface
public interface Lambda {
void yummy(Lambda this_);
default void yummy() {
yummy(this);
}
default void dummy(){
System.out.println("Call this..");
}
}
做不到。
JLS 15.27.2 解决这个问题:
Unlike code appearing in anonymous class declarations, the meaning of names and the this and super keywords appearing in a lambda body, along with the accessibility of referenced declarations, are the same as in the surrounding context (except that lambda parameters introduce new names).
The transparency of this (both explicit and implicit) in the body of a lambda expression - that is, treating it the same as in the surrounding context - allows more flexibility for implementations, and prevents the meaning of unqualified names in the body from being dependent on overload resolution.
Practically speaking, it is unusual for a lambda expression to need to talk about itself (either to call itself recursively or to invoke its other methods), while it is more common to want to use names to refer to things in the enclosing class that would otherwise be shadowed (this, toString()). If it is necessary for a lambda expression to refer to itself (as if via this), a method reference or an anonymous inner class should be used instead.
如果我没理解错的话。您正在尝试通过 lambda 实现调用接口中的默认方法。我觉得可以。
@FunctionalInterface
interface Value
{
String init(Value a);
default String add(String b)
{
return "added content "+b;
}
default String getResult()
{
String c = init(this);
return c;
}
}
public class Main
{
public static void main(String[] args)
{
Value v = a -> a.add("inpout"); // here I am calling add method in Value interface.
String c = v.getResult();
System.out.println(c);
}
}