Important New Features in java 8......
1) forEach() method in Iterable interface
Whenever we need to traverse through a Collection, we need to create an
Iterator
whose whole purpose is to iterate over and then we have business logic in a loop for each of the elements in the Collection. We might get ConcurrentModificationException if iterator is not used properly.
Java 8 has introduced forEach method in
java.lang.Iterable
interface so that while writing code we focus on business logic only. forEach method takes java.util.function.Consumer
object as argument, so it helps in having our business logic at a separate location that we can reuse. Let’s see forEach usage with simple example.2) default and static methods in Interfaces
If you read forEach method details carefully, you will notice that it’s defined in Iterable interface but we know that interfaces can’t have method body. From Java 8, interfaces are enhanced to have method with implementation. We can use
default
and static
keyword to create interfaces with method implementation.
We know that Java doesn’t provide multiple inheritance in Classes because it leads to Diamond Problem. So how it will be handled with interfaces now, since interfaces are now similar to abstract classes. The solution is that compiler will throw exception in this scenario and we will have to provide implementation logic in the class implementing the interfaces.
Notice that both the interfaces have a common method log() with implementation logic.
As you can see that
Interface1
has static method implementation that is used in MyClass.log()
method implementation. Java 8 uses default and static methods heavily in Collection API and default methods are added so that our code remains backward compatible.
If any class in the hierarchy has a method with same signature, then default methods become irrelevant. Since any class implementing an interface already has Object as superclass, if we have equals(), hashCode() default methods in interface, it will become irrelevant. Thats why for better clarity, interfaces are not allowed to have Object class default methods.
3)Functional Interfaces and Lambda Expressions
If you notice above interfaces code, you will notice @FunctionalInterface annotation. Functional interfaces are new concept introduced in Java 8. An interface with exactly one abstract method becomes Functional Interface. We don’t need to use @FunctionalInterface annotation to mark an interface as Functional Interface. @FunctionalInterface annotation is a facility to avoid accidental addition of abstract methods in the functional interfaces. You can think of it like @Override annotation and it’s best practice to use it.
java.lang.Runnable
with single abstract method run() is a great example of functional interface.
One of the major benefits of functional interface is the possibility to use lambda expressions to instantiate them. We can instantiate an interface with anonymous class but the code looks bulky.
Since functional interfaces have only one method, lambda expressions can easily provide the method implementation. We just need to provide method arguments and business logic. For example, we can write above implementation using lambda expression as:
If you have single statement in method implementation, we don’t need curly braces also. For example above Interface1 anonymous class can be instantiated using lambda as follows:
So lambda expressions are means to create anonymous classes of functional interfaces easily. There are no runtime benefits of using lambda expressions, so I will use it cautiously because I don’t mind writing few extra lines of code.
A new package
java.util.function
has been added with bunch of functional interfaces to provide target types for lambda expressions and method references. Lambda expressions are a huge topic, I will write a separate article on that in future.
Comments
Post a Comment