lambda可以访问其目标功能接口的成员吗?

时间:2015-02-28 10:39:05

标签: java lambda java-8

我使用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表达式实现这个场景?

3 个答案:

答案 0 :(得分:9)

无法完成。

JLS 15.27.2解决了这个问题:

  

与匿名类声明中出现的代码不同,含义为   名称以及出现在lambda体中的this和super关键字,   以及引用声明的可访问性是相同的   如在周围的上下文中(除了lambda参数引入   新名字。)

     

这个(透明和隐含)在透明体中的透明度   lambda表达式 - 也就是说,将其视为与...相同   周围环境 - 允许更多的实施灵活性,以及   防止身体中不合格名字的含义   取决于超载分辨率。

     

实际上, lambda表达式需要不常见   谈论自己(要么递归地调用自己,要么调用它   其他方法),而更常见的是想要使用名称来引用   在封闭类中的东西,否则将被遮蔽   (this,toString())。 如果有必要使用lambda表达式   引用自身(好像通过这个),方法引用或匿名   应该使用内部类。

答案 1 :(得分:8)

内部类实现起作用,因为代码被调用,就好像你编码:

check.activate(new Lambda() {
  @Override
  public void yummy() {
    this.dummy();
  }
});

我们现在的问题是lambdas没有引入新的范围。因此,如果您希望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..");
  }
}

答案 2 :(得分:0)

如果我理解正确的话。您正尝试通过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);

    }
}