Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can we not use default methods in lambda expressions?

I was reading this tutorial on Java 8 where the writer showed the code:

interface Formula {     double calculate(int a);      default double sqrt(int a) {         return Math.sqrt(a);     } } 

And then said

Default methods cannot be accessed from within lambda expressions. The following code does not compile:

Formula formula = (a) -> sqrt( a * 100); 

But he did not explain why it is not possible. I ran the code, and it gave an error,

incompatible types: Formula is not a functional interface`

So why is it not possible or what is the meaning of the error? The interface fulfills the requirement of a functional interface having one abstract method.

like image 366
codegasmer Avatar asked Oct 13 '15 17:10

codegasmer


People also ask

Can lambda expressions be used to implement interfaces having default and static methods?

You can define a lambda expression that would represent an A instance regardless of the context you are in. It can be a static interface method, it could be a default interface method.

Can we have default method in functional interface?

A functional interface can contain default and static methods which do have an implementation, in addition to the single unimplemented method.

Can we override default method from functional interface?

If you have default method in an interface, it is not mandatory to override (provide body) it in the classes that are already implementing this interface. In short, you can access the default methods of an interface using the objects of the implementing classes.

What is the default return type of lambda expression?

A return statement is not an expression in a lambda expression. We must enclose statements in braces ({}). However, we do not have to enclose a void method invocation in braces. The return type of a method in which lambda expression used in a return statement must be a functional interface.


1 Answers

It's more or less a question of scope. From the JLS

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).

In your attempted example

Formula formula = (a) -> sqrt( a * 100); 

the scope does not contain a declaration for the name sqrt.

This is also hinted at in the JLS

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.

I think it could have been implemented. They chose not to allow it.

like image 137
Sotirios Delimanolis Avatar answered Oct 05 '22 03:10

Sotirios Delimanolis