Apr 3, 2014

Top 6 Java 8 features you can start using now

Unlike Java 7, Java 8 has some significant changes. You can get familiarized with the the following simple working code. All you need is Java 8 installed on your machine.

#1: Interface can have static and default methods. This tries to solve the diamond (aka multiple inheriance) issue. In the past it was essentially impossible for Java libraries to add methods to interfaces. Adding a method to an interface would mean breaking all existing code that implements the interface. Now, as long as a sensible default implementation of a method can be provided, library maintainers can add methods to these interfaces. The static methods serve as utility methods, hence you don't need a separate helper class.

#2: Lambda expression for supporting closures, which simplifies your code. In the past, you need to write anonymous classes. Lambda expressions are anonymous methods which are intended to replace the bulkiness of anonymous inner classes with a much more compact mechanism.

Here is a basic example that covers #1 and #2. A simple button click example.

Let's define an interface with a static method (e.g. a utility function) and two default methods as shown below.

package com.java8.examples;

import java.awt.event.ActionEvent;

public interface Test {

 //Java 8: static method in an interface
 static void doSomething(ActionEvent event) {
        System.out.println("B1 clicked .....");
 default void doAnotherSomething(ActionEvent event) {
        System.out.println("B2 clicked .....");
 //Java 8: default method in interface 
 default void doWork(){
  System.out.println("executing default method");

Define the TestImpl class, which implements the interface Test. The TestImpl uses closures via lambda expressions and makes use of the methods implemented in the interface Test.

package com.java8.examples;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.Button;
import javax.swing.JFrame;

public class TestImpl implements Test {

 public static void main(String[] args) {

  JFrame frame = new JFrame();
  frame.setLayout(new FlowLayout());

  Button button1 = new Button("B1");
  Button button2 = new Button("B2");
  Button button3 = new Button("B3");
  Button button4 = new Button("B4");

  //Java 8: Lambda expressions & invocation of concrete methods in interface
  //invokes static method on the interface
  button1.addActionListener(Test::doSomething); //static method reference
  Test testObj = new TestImpl();
  button2.addActionListener(testObj::doAnotherSomething); //instance method reference
  //input is e and result is println(..) and doWork() functional interface method invocation
  button3.addActionListener((e) -> {System.out.println("B3 clicked ...");
                                     testObj.doWork(); });
  //old way: pre Java 8: Anonymous inner class
  button4.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    System.out.println("B4 clicked");


If you click on all 4 buttons from B1 to B4, you will get an output of

B1 clicked .....
B2 clicked .....
B3 clicked ...
executing default method
B4 clicked

Q. How does " button3.addActionListener((e) -> {System.out.println("B3 clicked ..."); testObj.doWork(); }); " know what method to execute? Did you notice that there is no new ActionListener( ) and no public void actionPerformed(ActionEvent event)?

A. Here the compiler understands that there is only one method in the ActionListener interface and that takes only one parameter. So obviously, it decides (finalizes) that the e as a reference to ActionEvent.

The functional interfaces that are annotated with @FunctionalInterface in Java 8 ensures that you can only define one abstract method. You can define as many default and static method implementations as you want.

#3 Java 8 adopts Joda as its native date & time framework. Due to what was perceived as a design flaw in Joda, Java 8 implemented its own new date / time API from scratch.  The new APIs were designed with simplicity in mind.

All the core classes in the new API are constructed by fluent factory methods. When constructing a value by its constituent fields, the factory is called of; when converting from another type, the factory is called from.

package com.java8.examples;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;

public class TimeTest {

 public static void main(String[] args) {
  // The current date and Time
  LocalDateTime timePoint =;
  System.out.println("now=" + timePoint);
  //10th of Jan  2012
  LocalDate pastDate = LocalDate.of(2012, Month.JANUARY, 10); 
  System.out.println("pastDate=" + pastDate);
  LocalTime mathsClassTonight = LocalTime.of(19, 30); 
  System.out.println("mathsClassTonight=" +  mathsClassTonight);
  mathsClassTonight = LocalTime.parse("19:30:50"); // From a String
  System.out.println("mathsClassTonight=" +  mathsClassTonight);
  //add 12 days to pastDate
  LocalDate plusDays = pastDate.plusDays(12);
  System.out.println("pastPlus12days=" +  plusDays);
  LocalDate epochDay = LocalDate.ofEpochDay(150); // 150 days from 01/01/1970
  System.out.println("epochDay=" +  epochDay);



The output will be:


Features 3 - 6 in Top 6 Java 8 features you can start using now -- part 2

Labels: ,


Post a Comment

Subscribe to Post Comments [Atom]

Links to this post:

Create a Link

<< Home