Java 8 Lambda in details part IV : Multiple inheritance resolution for defender methods

In this post we’ll look at conflict resolution rules for multiple inheritance introduced along with defender methods in JDK 8.

DISCLAIMER: all the details exposed in this post were observed related to the JDK 8 demo version as of July 10th 2012. Since the JDK is still in beta, some assertions may not hold in future

Please note that all the example code in this post can be found on my GitHub repository https://github.com/doanduyhai/Java8_Lambda_In_Details

 

I Method lookup rules

With JDK 8 now we can provide a default implementation for declared abstract methods in an interface, a defender method.

Since it is possible for a class to implement multiple interfaces it will lead de-facto to the possibility of multiple inheritance if more than 2 interfaces in the hierarchy are providing default implementation for the same abstract method.

Please note that unlike a real multiple inheritance, defender method multiple inheritance is only behavioral, no state (field) is inherited.

Below are the rules to lookup method implementation:

1) First search for this method in the class (not interface) hierarchy from the current class up to the root Object class.

1a) If a matching non abstract method is found, use it (even if matching defender methods are found).

Lambda_Defender_Inheritance_NonAbstractMethodInHierarchy

1b) If a matching abstract class is found then force the current class to implement it (even if a matching defender method can be found in the hierarchy) otherwise compilation error.

Lambda_Defender_Inheritance_AbstractMethodInHierarchy

The general rule of thumb is: method definition from class hierarchy, abstract or not, has priority over defender methods.

2) If no matching method is found in the class hierarchy, examine the interface hierarchy. Prune all the branches and only take “leaf” interfaces in the tree.

2a) If a matching defender method is found in only one of those “leaf” interfaces, use it

2b) If more than one “leaf” interfaces provide defender methods, raise a compilation error to force the user to explicitely define the defender method to be used.

The above rules are simplifications from the more formal rules defined in http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf

 

II Resolution examples

In this chapter, we present some concrete example of method resolution

A From SuperInterface

In this scenario, the method implementation comes from a defender method defined in a SuperInterface

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the SameSuperDefenderMethod.bat(SameSuperDefenderMethod.sh) script

 

B From most specific interface

In this scenario, the method implementation comes from the defender method of the most specific inherited interface.

Lambda_Defender_Inheritance_FromMostSpecificInterface

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the MostSpecificDefender.bat(MostSpecificDefender.sh) script

 

C Conflicting defenders

When there are more than one matching defender method from “leaf” interfaces, we have a conflict and compilation issue

Lambda_Defender_Inheritance_ConflictingDefenders

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the ConflictingDefenders.bat(ConflictingDefenders.sh) script

 

D Priority to class hierarchy

It a matching method is found in the class hierarchy, be it abstract, then it prevails over all defender methods.

Lambda_Defender_Inheritance_PriorityToClassHierarchy

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the PriorityToHierarchy.bat(PriorityToHierarchy.sh) script

 

E Removed defender

Sometimes, an interface can “remove” the default implementation provided by one of its superinterfaces. Removal is done simply by overriding the defander method without providing any default implementation

public interface SuperDefender
{
	String changeInput(String input) default
	{
		return input.trim();
	}
}

public interface RemovedDefenderInterface extends SuperDefender
{
	String changeInput(String input); // Default removed here
}	

In such case the class implementing the interface needs to override the method.

Lambda_Defender_Inheritance_RemovedDefenderInterface

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the RemovedDefender.bat(RemovedDefender.sh) script

 

F Resolving defender conflics at interface level

Whenever a conflict occurs for a defender method inheritance at interface level, we can resolve it by specifying the version of the defender to be used.

Lambda_Defender_Inheritance_ResolvedDefenderConflictAtInterface

public interface ResolvedDefenderConflictInterface extends Defender1, Defender2
{
	String changeInput(String input) default
	{
		return Defender2.super.changeInput(input);
	}
}

Please notice the introduction of the new syntax for the super keyword. With JDK 8 you can prefix it with the concrete interface to be used as “parent”.

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the ResolvedDefenderConflictsAtInterface.bat(ResolvedDefenderConflictsAtInterface.sh) script

 

G Resolving defender conflics at class level

Similarly the resolution for defender method conflict can be done at implementing class level.

public class ResolvedDefenderConflictsAtClass implements Defender1, Defender2
{
	public String changeInput(String input)
	{
		return Defender1.super.changeInput(input);
	}
	...
	...
}

The syntax for indicating which super interface to be used is the same (line 5).

The above scenario can be illustrated by a code example on GitHub at https://github.com/doanduyhai/Java8_Lambda_In_Details. Just execute the ResolvedDefenderConflictsAtClass.bat(ResolvedDefenderConflictsAtClass.sh) script

To be continued …
 
 

2 Comments

  1. About Java

    good article.. eagerly looking forward to Java 8 Lambda.. 🙂

    Reply
  2. Funny Cop Prank

    My developer is trying to persuade me to move to .net from
    PHP. I have always disliked the idea because of the costs.
    But he’s tryiong none the less. I’ve been using WordPress on several websites for about a year and am anxious about switching to another platform.

    I have heard fantastic things about blogengine.
    net. Is there a way I can import all my wordpress content into it?
    Any help would be really appreciated!

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.