【问题标题】:Java 8: replace anonymous class with lambdaJava 8:用 lambda 替换匿名类
【发布时间】:2018-04-27 11:37:16
【问题描述】:

我在替换这个特定示例时遇到问题:

Consumer consumer = new DefaultConsumer(channel) {
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
            throws IOException {
        String message = new String(body, "UTF-8");
        System.out.println(" [x] Received '" + message + "'");
    }
};

是否可以用 lambda 替换它,因为它使用 DefaultConsumer 的非默认构造函数?

来自rabbitMQ java教程 -> LINK to whole class

【问题讨论】:

  • 这取决于DefaultConsumer。有不止一种抽象方法吗?你是如何使用Consumer consumer 的?
  • @slim,谢谢,这就是回答我的问题,不,它不能用于它!
  • 如果您为 multiple DefaultConsumers 执行此操作,您可以创建一个辅助方法,将 lambda 作为输入并返回 Defaultconsumer 的匿名子类.

标签: java lambda java-8


【解决方案1】:

不,你不能。 DefaultConsumer 不是 FunctionalInterface(也不能是:more info here)因此不是 lambda 目标。

说明:

每个匿名类都可以用 lambda 表达式代替吗?

答案是否定的。您可以为非最终类和接口创建匿名类。 lambda 表达式不一样。这些只能用于需要 SAM 接口的地方,即只有一个单一抽象方法的接口(在 Java 8 之前,每个接口方法都是抽象的,但由于 Java 8 接口也可以有默认和静态方法,它们是'不抽象,因为它们有实现)。

那么哪些匿名类可以用 lambda 表达式代替呢?

只有实现 SAM 接口的匿名类(如 Runnable、ActionListener、Comparator、Predicate)才能被 lambda 表达式替换。 DefaultConsumer 不能是 lambda 目标,因为它甚至不是接口。

那么消费者呢?

尽管Consumer 是一个接口,但它不是 SAM 接口,因为它有多个抽象方法,因此它也不能是 lambda 目标。

【讨论】:

  • 这里的结果变化不大,但FunctionalInterface 不是强制性的。
  • 一个接口可以是一个“功能性接口”而不需要注解@FunctionInterface——但是DefaultConsumer不是一个功能性接口有很多原因——不是一个接口;多种方法都不是抽象的...
  • @AxelH 我知道,但无论如何它必须是 SAM type 才能成为 lamda 目标
  • 我知道,这就是为什么这个 “对结果没有太大改变” ;) 但解释有点宽泛,我更喜欢你的评论作为解释。因为您的答案在“不是FunctionnalInterface”和“不能是FunctionnalInterface”之间没有区别,因为注释本身是可选的。
  • @AxelH 理解。编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
相关资源
最近更新 更多