Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do lambdas in Java 8 disallow forward reference to member variables where anonymous classes don't?

Tags:

People also ask

Does lambda expression eliminates the need of anonymous class?

Lambda expressions are introduced in Java 8. These are used primarily to define inline implementation of a functional interface, i.e., an interface with a single method only. Lambda expression eliminates the need of anonymous class and gives a very simple yet powerful functional programming capability to Java.

Can we replace anonymous class with lambda?

Since the most common use of Anonymous class is to provide a throwaway, stateless implementation of abstract class and interface with a single function, those can be replaced by lambda expressions, but when you have a state field or implementing more than one interface, you cannot use lambdas to replace the anonymous ...

Are lambdas anonymous classes?

A lambda expression is a short form for writing an anonymous class. By using a lambda expression, we can declare methods without any name. Whereas, Anonymous class is an inner class without a name, which means that we can declare and instantiate class at the same time.

What are the advantages of lambda expression over anonymous methods?

Fewer Lines of Code − One of the most benefits of a lambda expression is to reduce the amount of code. We know that lambda expressions can be used only with a functional interface. For instance, Runnable is a functional interface, so we can easily apply lambda expressions.


The following class contains a member variable runnable which is initialized with an instance of an anonymous inner class. The inner class references the same member:

class Example {     Runnable runnable = new Runnable() {         @Override         public void run() {             System.out.println(runnable);         }     }; } 

This is not a problem as long as the method is not executed before the member has been assigned and the JLS allows such a reference.

The declaration of the member variable could theoretically be converted to a lambda expression like this:

Runnable runnable = () -> System.out.println(runnable); 

To my understanding, this is functionally equivalent to the previous example, but it is rejected by javac 1.8.0_05 with the following error message:

Error:(2, 54) java: self-reference in initializer 

While that statement is true, I do not see why this was disallowed. Was this intentionally disallowed, maybe because lambda expressions are compiled to different byte code which would lead to problems if it was allows? Or was just disallowed because there were already problems with these references when they were used in anonymous inner classes? Or was it unintentionally disallowed by the JLS writers? Or is it a bug in javac?