JAVA’s Inner Anonymous Class vs Lambda — The thin line
Inner class were added in Java 1.1, while Lambda availability came only in version 1.8 together with many cool features.
The following article will discuss the differences between those features.
A “deep diver” Java developer may wonder about the most simple question when observing the following line of code:
Runnable r = () -> System.out.println(“I ran”)
Is the Labmda above an anonymous class ?
As many of you may know, Runnable is a functional interface and ‘()->XYZ’ is the lambda function.
The article assume you are familiar with Lambda function and anonymous classes
Most of you probably assume the code is equal to one of the following:
Runnable r = new Runnable() {
public void run() {
System.out.print(“I ran”);
}
}
Or
class RunnableImpl implements Runnable {
public void run() {
System.out.print(“I ran”);
}
}Runnable r = new RunnableImpl() ;
In fact, the difference is quite big, the Lambda is an anonymous function while the other is an anonymous class.
We will deep dive to several topic and compare between the two.
1. Inheritress
Inner Anonymous Class: Extending abstract and concrete class is possible
Lambda: Extending is not possible
2. Interfaces
Inner Anonymous Class: Can implement any amount of interfaces with varied amount of functions.
Lambda: Must implement one interface with single abstract method. (default / static methods are not counted)
3. Variables
Inner Anonymous Class: We can declare variable in the instance level on local ones for the functions.
Lambda: declaring variable can only take place locally in the function but never on the instance level.
4. Using ‘this’
Inner Anonymous Class: “this” call will always refer the the Inner Anonymous Class and not the outer class who hold it.
Lambda: “this” call will refers to the outer class object that the lambda defined in. Just like a function in the outer class instance.
Example:
class A {
int counter = 0; public void myFunc() {
Callable r = () -> this.counter++;
r.call()
}
}
Example 2:
class A {
public void myFunc() {
int counter = 0;
Callable r = () -> this.counter++; <<< WILL NOT WORK
r.call()
}
}
5. .class file, reflection and class modification
Inner Anonymous Class: A dedicated .class file will be created, might be easier to modify class during runtime (JavaAssist, etc..)
Lambda: No .class file will be generated during compilation. it will generate the lambda as a private method for the outer class.
6. Memory
Inner Anonymous Class: Like any standard class, memory is assigned when during class instantiation.
Lambda: different story, it is being saved in the permanent memory of JVM.
Functional interface mostly being implemented as Lambdas, it is one of the main reasons Lambda functions where invented. Of course Lambda function will also make the code much clearer, much accurate and will reduce classes amount as one will not create many classes for a single function implementation.
Java maintainers did a fine work on Lambda development, the code can be significantly shrink using Java’s compiler and interpreters. Take a look at the following example:
Function f = (a + b) -> a*b
The compiler will automatically assume the variables are Number typed and following it evaluation it will also assume there is a return type of Number. Kudos to Java guys!
Lambda function are practically good when the code segment is stateless (e.g. sorting arrays, print collections, define TreeSet order, etc..), however, when external variables are needed than your code can slightly turn Spaghetti. And one will fine himself moving variables from a function to the class level even thought it being used only for the function.
class A {
// The following must be define in the class level
int myFuncTotal = 0; public void myFunc() {
List<Integer> arr = Arrays.asList(1, 2, 3, 4, 5);
arr.stream().forEach(a -> myFuncTotal + a);
}
}
Reminder, you cannot set this variable in the function where Lambda is being defined. The compiler will patch the lambda as a private method and function variable cannot be shared unless they are part of the class/instance.
“The Dark side of Lambda”, Java language is being developed from time to time and more features are being added. Some are more functional and other syntactic. As time passes by the gap between the written code and the actual compile one is getting greater. this make the code much harder to handle and follow upon failure. it a drawback but the the way many language are passes by.
To summarize both features are great, in the future we will more and more Lambda concepts being used. You need to consider the size and complexity of the segment you would like to wrap in order to decide which feature to use.
Enjoy!