Java 8 : Default method in Interface

Original article here:

This article contains…

  • What is Default methods ?
  • Why Default methods ?
  • Example of various scenarios using Default methods
  • Default methods and multiple inheritance
  • Behavior when extending interface.

Introduction:

In the Java programming language, an interface is a reference type, similar to a class, that can contain only constants, method signatures, static methods, and nested types. Method in an Interface does not have a body, and they are implicitly public abstract by default.

Wait, Above definition of interface was correct up to Java 7. In Java 8 release, Definition of interface is a bit broader then previous one.

From java 8, Interface can have default methods also.

What is Default Method ?

The method with default implementation in interface are Default methods, they can have body part also and these are non-abstract methods. These methods are useful to provide default implementations.

It can be inherited in the class which implements the interface and it can be Overridden also.

You specify that a method definition in an interface is a default method with the default keyword at the beginning of the method signature. All method declarations in an interface, including default methods, are implicitly public, so you can omit the public modifier.

Why Default method ?

Suppose at some point you want to add new functionality in declared interface, up to Java 7, If you will add a new method in declared an interface, you also have to define the implementation of the method in classes that are implementing that interface.

In java 8, You can add a default method containing the implementation and all the child class will inherit that method.

Bulk data operation in collection is added in Java 8 (Reference : http://openjdk.java.net/jeps/107), to implement that forEach() method is added in Collection interface. If we are adding abstract method in Collection interface, that will break all the existing code because each class has to implement that method.

Solving the issue, following default forEach() method is added in Collection interface,

interface Collection {
   default void forEach(Block action) {
      for (T t : this)
      action.apply(t);
   }
}

Example of default method :

interface HasBody {
   default void first() {
      System.out.println("This is first default method in HasBody interface.");
   }

   default void second() {
      System.out.println("This is second default method in HasBody interface.");
   }

   void third();
   }

class Demo implements HasBody {

   @Override
   public void second() {
      System.out.println("Overriding default method in child class.");
   }

   @Override
   public void third() {
      System.out.println("This is implemented abstract method of an interface.");
   }

   public void implement() {
      HasBody ref = new Demo();
      // Calling first() default method declared in HasBody interface.
      ref.first();

      // Calling Overridden default method of HasBody interface.
      ref.second();

      // Calling implemented method of HasBody interface.
      ref.third();
   }
}

In above example, there are three scenarios,

  1. first() method is default method in HasBody interface and Inherited in DefaultMethodDemo class.
  2. second() method is default method in HasBody interface and Overridden in DefaultMethodDemo class.
  3. third() method is abstract method in HasBody interface and Implemented in DefaultMethodDemo class.

Multiple inheritance and Default methods:

As the default methods in interface will be inherited in class that will implement interface and a class can implement more than one interface that may contain same method that defined default in interface. Multiple inheritance will be into the picture and because of that, ambiguity may be created.

Well, this situation is handled compile time in JDK 8

Example :

interface CreateAmbiguityOne {

   default void abc() {
      System.out.println("This method will create ambiguity.");
   }
}

interface CreateAmbiguityTwo {

   default void abc() {
      System.out.println("This method will create ambiguity.");
   }
}

class AmbiguousChild implements CreateAmbiguityOne,CreateAmbiguityTwo {
   // Ambiguouity in class.
}

Above code will not compile, Error will be

class Child inherits unrelated default for abc() from types CreateAmbiguityOn and CreateAmbiguityTwo.

However, Overriding abc() method in Child class will solve above ambiguity.

class Child implements CreateAmbiguityOne, CreateAmbiguityTwo {
   @Override
   public void abc() {
      System.out.println("Overriding abc() will solve Ambiguity.");
   }
}

Another point to note is extending a class that contains same method as default method in interface will not create ambiguity.
because Child class will Override the default method of interface by inherited method of Parent class.

Example :

class Parent {
   public void abc() {
      System.out.println("This method will override default method of interface in child class.");
   }
}

class ChildTwo extends Parent implements CreateAmbiguityOne {
   // This class has no ambiguity even if Parent class and CreateAmbiguityOne has same method.
   // Because,
   // Inherited abc() method of Parent class will Override default method of CreateAmbiguityOne in ChildTwo class.
}

Behavior of default method when we extend interface.

  • All the default methods of interface will be inherited in child interface.
  • Child interface can override the default method.
  • Child interface can declare default method of parent interface as abstract, that will force implementing class to Override the default method.

Example :

interface ChildInter extends HasBody {
   // All the default methods of HasBody interface will be inherited here.

   // Override the default method in child interface.
   default void first() {
      System.out.println("first() method is overriden in child interface.");
   }

   // Redefine the default method as abstract that will force subclass to Override the method.
   abstract void second();
}

class DemoTwo implements ChildInter {
   @Override
   public void second() {
      System.out.println("Subclass overriding default method of HasBody interface redefined in ChildInter.");
   }

   @Override
   public void third() {
      System.out.println("abstract method of HasBody interface.");
   }
}

More articles will be available soon on Java 8 and SCJP.

You can always clone the executable code of article posted on Java By Examples from github.com
Repository URL : https://github.com/ksarsecha/java8_in.git

– See more at: http://java8.in/java-8-default-method-in-interface/#sthash.6YlezEBk.dpuf

JAVA 8: Streaming a String

Streaming a String using Java 8.

public static void main(String[] args) {
        "hey duke".chars().forEach(c -> System.out.println((char)c));
    }

The parallel version does not preserve the order (and comes with additional overhead):

public static void main(String[] args) {
        "hey duke".chars().parallel().forEach(c -> System.out.println((char) c));
    }

Enjoy Java 8!

 

Changing Default HSQLDB to Use Database in Jboss 4.2.3 for JMS

As we know jboss uses HSQLDB for the jms persistence to modify this to persist the JMS messages to user Database like mysql, oracle, etc. Following changes as to be made in jboss 4.2.3. We assume the Postgres Database for this purpose.

1. Delete the hsqldb-ds.xml from JBOSS_HOME/server/[instance]/deploy folder.

2. Copy the respective database related ds file from JBOSS_HOME/docs/examples/jca/*-ds.xml file to deploy folder of your [instance].

3. Change the jndi-name in *-ds.xml file to “DefaultDS“.

4. Delete hsqldb-jdbc2-service.xml file from JBOSS_HOME/server/[instance]/jms folder.

5. Copy the respective database persitence manager service xml file *-jdbc2-service.xml from JBOSS_HOME/docs/examples/jms to JBOSS_HOME/server/[instance]/deploy/jms folder.

6. Change the jndi name in the *-jdbc2-service.xml to “DefaultDS“, jboss.jca:service=DataSourceBinding,name=DefaultDS

7. Rename the hsqldb-jdbc-state-service.xml to respective database name *-jdbc-state-service.xml, its optional you can keep the file as it is.

8. Copy the respective database connector jar file to /JBOSS_HOME/server/[instance]/lib folder.

Now the configuration is modified for the jms persistence to user database and data will persist to jms_message table only when the huge number of jms are generated and its a temporary storage once the jms message is consumed it will deleted automatically from the jms_message table.

How To Calculate Date And Time Difference In Java

In this tutorial, we show you 2 examples to calculate date / time difference in Java :

  1. Manual time calculation.
  2. Joda time library.

1. Manual time calculation

Converts Date in milliseconds (ms) and calculate the differences between two dates, with following rules:

1000 milliseconds = 1 second
60 seconds = 1 minute
60 minutes = 1 hour
24 hours = 1 day

Class DateDiferentExample.java

package br.com.ziben.date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateDifferentExample {

	public static void main(String[] args) {

		String dateStart = "01/30/2013 09:29:58";
		String dateStop = "01/31/2013 10:31:48";

		// HH converts hour in 24 hours format (0-23), day calculation
		SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

		Date d1 = null;
		Date d2 = null;

		try {
			d1 = format.parse(dateStart);
			d2 = format.parse(dateStop);

			// in milliseconds
			long diff = d2.getTime() - d1.getTime();

			long diffSeconds = diff / 1000 % 60;
			long diffMinutes = diff / (60 * 1000) % 60;
			long diffHours = diff / (60 * 60 * 1000) % 24;
			long diffDays = diff / (24 * 60 * 60 * 1000);

			System.out.print(diffDays + " days, ");
			System.out.print(diffHours + " hours, ");
			System.out.print(diffMinutes + " minutes, ");
			System.out.print(diffSeconds + " seconds.");

		} catch (Exception e) {
			e.printStackTrace();
		}
 	}
}

Result…

1 days, 1 hours, 1 minutes, 50 seconds.

Why seconds and minutes need %60, and hours %24? If you change it to:

long diffSeconds = diff / 1000;

The result will be

1 days, 1 hours, 1 minutes, 90110 seconds.

The “90110” is the total number of seconds difference between date1 and date2, this is correct if you want to know the differences in seconds ONLY.

To display difference in “day, hour, minute and second” format, you should use a modulus (%60) to cut off the remainder of seconds (90060). Got it? The idea is applied in minutes (%60) and hours (%24) as well.

90110 % 60 = 50 seconds (you want this)
90110 - 50 = 90060 seconds (you dont want this)

2. Joda Time Example

Here’s the equivalent example, but using Joda time to calculate differences between two dates.

P.S This example is using joda-time-2.1.jar

Class JodaDateDifferentExample.java

package br.com.ziben.date;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Hours;
import org.joda.time.Minutes;
import org.joda.time.Seconds;

public class JodaDateDifferentExample {

  public static void main(String[] args) {

	String dateStart = "01/30/2013 09:29:58";
	String dateStop = "01/31/2013 10:31:48";

	SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

	Date d1 = null;
	Date d2 = null;

	try {
		d1 = format.parse(dateStart);
		d2 = format.parse(dateStop);

		DateTime dt1 = new DateTime(d1);
		DateTime dt2 = new DateTime(d2);

		System.out.print(Days.daysBetween(dt1, dt2).getDays() + " days, ");
		System.out.print(Hours.hoursBetween(dt1, dt2).getHours() % 24 + " hours, ");
		System.out.print(Minutes.minutesBetween(dt1, dt2).getMinutes() % 60 + " minutes, ");
		System.out.print(Seconds.secondsBetween(dt1, dt2).getSeconds() % 60 + " seconds.");

	 } catch (Exception e) {
		e.printStackTrace();
	 }
  }

}

Result:

1 days, 1 hours, 1 minutes, 50 seconds.

Let me know if you have alternative ways 🙂

 

How to call a web service from a browser

I’ve been working with web services a lot this past week, specifically with Apache CXF, and here are a few notes I’ve learned about hitting one of my web services from a browser.

Looking at the WSDL for a web service from a browser

To view the WSDL document for the web service I created named UserService, I just went to the following URL in my browser:

http://localhost:8080/test/services/UserService?wsdl

For my purposes right now I’m just running the web service using the CXF core under JBoss Tomcat, so my UserService web service is available at that URL.

Calling a web service set method from a browser

To call a method on my web service named setTwoNumbers, which shows up in the WSDL as setTwoNumbers(int param0, int param1), I typed this as a URL in my browser:

http://localhost:8080/test/services/UserService/setTwoNumbers?param0=5&...

Calling a web service get method from a browser

After first calling my method to set the two parameters, I was then able to call these two methods and get my numbers (5 and 10) back from them:

http://localhost:8080/test/services/UserService/getNum1
http://localhost:8080/test/services/UserService/getNum2