Introduction
Java 8 is a major release for JAVA programming language. The new features in Java 8 includes
- Functunal programming with Lamda Expression
- Default method: Allows developer to add new methods to the interfaces without breaking the existing implementation of these interface.
- Method reference : Referencing functions by their names instead of invoking them directly
- Javascript engine: A Java based engine to execute Javascript code
- Date time API: New set of API o manipulate date and time
Functional Programming
In traditional java programing there are some limitations. E.g.
- There was no way to define a java method on the fly. Generally, the method will be inside a class. An instance needs to be created to call the method. In Java8 using lamda expression this problem is addressed. A method can be created on the fly.
- There was no way to pass method as an argument of a function or returning a method body for that instance.
- Lamda Expression is
- an anonymous function
- a method without declaration, i.e. access modifier, return value declaration, and names
- a way to save effort in writing method (in a class) which may not be used repeatedly. The method is defined at the same place.
- Few different types of Lamda Expression examples are given below.
Foreach loop
Functional Interface
Functional Interface has been introduced in Java 8. In functional interface, only one abstract method is allowed.
FunctionalIntf.java: This is an functional interface having one and only one abstruct interface. Remaining interfaces must have default implementation.
package com.ashish.java8.lamda.expr.functional.intf;
@FunctionalInterface
public interface FunctionalIntf {
/**
* Only one abstract interface is allowed in a functional interface
*/
public abstract void doSomeWork();
/**
* More than one interface needs to have default implementation
*/
public default void doSomeWork1() {
System.out.println("Some default implementation in functional interface");
}
}
SomeImplClass.java : This class implements a method having reference to functional interface.
package com.ashish.java8.lamda.expr.functional.intf;
public class SomeImplClass {
public void execute(FunctionalIntf functionalIntf) {
functionalIntf.doSomeWork();
}
}
FunctionalIntfMain.java: This class shows how to call SomeImplClass.execute() method in traditional approach and in Java 8 way.
package com.ashish.java8.lamda.expr.functional.intf;
public class FunctionalIntfMain {
public static void main(String[] args) {
// **************************************
// Traditional approach - Anonymous class
// **************************************
SomeImplClass someImplClass = new SomeImplClass();
someImplClass.execute(new FunctionalIntf() {
@Override
public void doSomeWork() {
System.out.println("Traditional approach: Do some work using anonymous class");
}
});
// **************************************
// Java8 approach - Using Lamda Expression
// **************************************
someImplClass.execute(() -> {
System.out.println("Java8: Do some work using Lamda Expression");
});
}
}
Default Method Example
Suppose there are two different companies Sony and Erricson manufactures cell phones. Hence they have two seperate interfaces called ErricsonPhoneIntf and SonyPhoneIntf. In both the interfaces have makeCall() default method implemented. Now while manufacturing Sony Experia C model by default ErricsonPhoneIntf.makeCall() default implementation will get inherited.
While manufacturing Sony Experia Z model, the company wants to add some additional features then makeCall() method has to be inherited.
Now suppose these two brands merged and rebranded as SonyErricson. Now SonyErricson will inherit from both SonyIntf and ErricsonIntf. Now there will be a confusion in makeCall() method selection. This problem is called Diamond Problem in java. In Java8, this problem is addressed. Please have a look into SonyErricsonPhone class given below.
SonyPhoneIntf.java
package com.ashish.java8.defaultMethods;
public interface SonyPhoneIntf {
default void makeCall() {
System.out.println("Make call implemented by Sony");
}
}
SonyExperiaCPhone.java
package com.ashish.java8.defaultMethods;
public class SonyExperiaCPhone implements SonyPhoneIntf {
}
SonyExperiaZPhone.java
package com.ashish.java8.defaultMethods;
public class SonyExperiaZPhone implements SonyPhoneIntf {
/**
* Below method overrides the makeCall() method in parent interface
*/
@Override
public void makeCall() {
System.out.println("Make call implemented by Sony. Also some new features added");
}
}
ErricsonPhoneIntf.java
package com.ashish.java8.defaultMethods;
public interface ErricsonPhoneIntf {
default void makeCall() {
System.out.println("Make call implemented by Erricson");
}
}
SonyErricsonPhone.java
package com.ashish.java8.defaultMethods;
public class SonyErricsonPhone implements SonyPhoneIntf, ErricsonPhoneIntf {
/**
* This method breaks the java diamond problem at the time of multiple inheritance.
* This method clearly specifies the which version of makeCall() method to be taken
*/
public void makeCall() {
ErricsonPhoneIntf.super.makeCall();
}
}
DefaultMainMethod.java
package com.ashish.java8.defaultMethods;
public class DefaultMainMethod {
public static void main(String args[]) {
SonyErricsonPhone sonyErricsonPhone = new SonyErricsonPhone();
sonyErricsonPhone.makeCall();
SonyExperiaCPhone sonyExperiaCPhone = new SonyExperiaCPhone();
sonyExperiaCPhone.makeCall();
SonyExperiaZPhone sonyExperiaZPhone = new SonyExperiaZPhone();
sonyExperiaZPhone.makeCall();
}
}
Output
The output of the program is given below