6

I'm having problem in replacing this particular example:

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 + "'");
    }
};

Is it possible to replace that with lambda as it uses non-default constructor for DefaultConsumer?

It's from rabbitMQ java tutorial -> LINK to whole class

Juan Carlos Mendoza
  • 5,736
  • 7
  • 25
  • 50
doublemc
  • 3,021
  • 5
  • 34
  • 61
  • It depends on `DefaultConsumer`. Is there more than one abstract method ? How are you using `Consumer consumer` ? – AxelH Nov 14 '17 at 13:35
  • @AxelH https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/DefaultConsumer.html – slim Nov 14 '17 at 13:36
  • @slim, thanks, that's answer my questions, nope it can't be used for it! – AxelH Nov 14 '17 at 13:40
  • If you do this for _multiple_ `DefaultConsumer`s though, you could create a helper method, taking a `lambda` as input and returning an anonymous subclass of `Defaultconsumer`. – tobias_k Nov 14 '17 at 13:43

1 Answers1

7

No you can't. DefaultConsumer is not a FunctionalInterface (and can't be: more info here) hence is not a lambda target.

Explanation:

Can every anonymous class be replaced by a lambda expression?

The answer is no. You can create an anonymous class for non-final classes and interfaces. Is not the same for lambda expressions. These can be only used where a SAM interface is expected, i.e. interfaces with only a Single Abstract Method (before Java 8 every interface method was abstract but since Java 8 interfaces can also have default and static methods which aren't abstract because they have implementation).

So which anonymous classes can be replaced with a lambda expression?

Only anonymous classes which are implementations of a SAM interface (like Runnable, ActionListener, Comparator, Predicate) can be replaced by a lambda expression. DefaultConsumer cannot be a lambda target because is not even an Interface.

And what about Consumer?

Even though Consumer is an Interface, it is not a SAM Interface because it has more than 1 abstract method so it can't be a lambda target either.

shmosel
  • 49,289
  • 6
  • 73
  • 138
Juan Carlos Mendoza
  • 5,736
  • 7
  • 25
  • 50
  • Doesn't change much on the result here but [`FunctionalInterface`](https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html) is not mandatory . – AxelH Nov 14 '17 at 13:37
  • 2
    An interface can be a "functional interface" without being annotated `@FunctionInterface` -- but `DefaultConsumer` is not a functional interface for a number of reasons -- not an interface; multiple methods none of which is abstract... – slim Nov 14 '17 at 13:39
  • 1
    @AxelH I know but it needs to be a [SAM type](https://stackoverflow.com/questions/17913409/what-is-a-sam-type-in-java) anyway to be a lamda target – Juan Carlos Mendoza Nov 14 '17 at 13:40
  • 1
    I know, that's why this _"doesn't change much on the result"_ ;) but the explanation is a bit broad, I prefer your comment as an explanation. Because your answer don't do the difference between "is not a `FunctionnalInterface`" and "**can not be** a `FunctionnalInterface`" since the annotation itself is optional. – AxelH Nov 14 '17 at 13:42
  • 1
    @AxelH understood. Edited my answer. – Juan Carlos Mendoza Nov 14 '17 at 13:48