当前位置: 首页 > 知识库问答 >
问题:

有没有办法把一个现有的接口变成一个功能接口?

海岳
2023-03-14

我使用的界面看起来大致如下:

public interface ObjectListener {
    public void objectAdded(Object o);
    public void objectRemoved(Object o);
}

并且我目前正在使用一个匿名类来实现接口,但我并不关心这两种方法中的一种。大致如下:

someObject.addListener(new ObjectListener() {

    @Override
    public void objectAdded(Object o) {
        doSomething(o);
    }

    @Override
    public void objectRemoved(Object o) {}
});

现在,我已经在Java8中尽可能地使用新的lambda表达式,我想在这种情况下使用增加的简单性。毕竟,我只是在实现其中的一个方法,但由于接口中有两个方法,所以我不能在一个lambda表达式中使用它。

共有1个答案

俞俊逸
2023-03-14

为了在lambda表达式中重用不是函数接口的现有接口,您还必须使用新的Java8特性,默认方法。

在这种情况下,如果希望使用lambda表达式来代替匿名类,则必须执行以下操作。

首先,您需要将ObjectListener重新定义为一个新接口:

public interface ObjectAddedListener extends ObjectListener {
    @Override
    default public void objectRemoved(Object o) {}
}

我们只是简单地将一个空的默认实现添加到我们不关心的方法中,这使得objectAdded()方法成为接口中唯一的抽象方法。

然后您可以使用新类型来代替任何ObjectListener,并且由于在新接口中只有一个没有实现的方法,所以您可以在lambda表达式中使用它,如下所示:

ObjectAddedListener listener = o -> doSomething(o);
someObject.addListener(listener);

注意,如果希望在addListener()方法中直接使用这个新类型,首先需要将lambda表达式转换为新定义的类型,如下所示:

someObject.addListener((ObjectAddedListener) o -> doSomething(o));
 类似资料:
  • 我可以使用retrolambda启用具有Android API级别的lambdas 这同样有效 但这个不行 最后一个适用于Android API Level 24,但在其他设备上此代码会导致崩溃 我尝试启用Java8.前两个代码示例仍然可以工作,尽管Butter停止了工作。https://developer.android.com/preview/j8-jack.html#configuratio

  • 是否可以像所附图像一样在表格中放置一个按钮?

  • 我基本上想要一个EC2,一个接口在公共子网,一个在私有子网。我应该能够通过公共接口从外界SSH,私有网络将用于与私有网络中的数据库通信。 在地形上。。。 我在该 VPC 中创建了一个 VPC,两个子网(一个公共子网,一个私有子网)。 创建了一个互联网网关,即 VPC 中的路由表,其路由为 0.0.0.0/0 至 IGW 已在与公有子网和路由表之间创建路由关联。 已创建一个 EC2 实例,其中一个接

  • 问题内容: 根据MDN 文档: 该 方法冻结对象:即,防止向其添加新属性;防止现有属性被删除;并防止更改现有属性或其可枚举性,可配置性或可写性。本质上,对象实际上是不可变的。该方法返回被冻结的对象。 我期望在某个日期调用冻结会阻止对该日期进行更改,但是它似乎没有用。这是我正在做的(运行Node.js v5.3.0): 我本以为调用会失败或什么都不做。任何想法如何冻结日期? 问题答案: 有没有办法O

  • 问题内容: 首先,我阅读了埃里克森对“为什么不能在Java接口中定义静态方法?”的有用答复。。这个问题不是关于“为什么”的问题,而是关于“然后如何做”的问题。 编辑:我的原始示例不适当地,但我将其保留在下面。 虽然我现在确信在大多数情况下我想做的是过度矫kill过正,但在一种情况下可能需要这样做: 我再举一个例子。现在,让我们采用一个适合于查找表的复杂功能,例如Bessel函数。这必须进行初始化,

  • 我在Kubernetes集群中有一个服务和RabbitMQ。我想做的是,我希望服务的不同实例(或副本)在启动时声明一个全新的队列。这些队列将绑定到同一个exchange。 我可以在这里放一个最后的变量吗: 本质上,我只需要一种方法,用生成的名称创建一个队列,然后使用@RabbitListener侦听这个队列。