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).
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.
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.
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
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.
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.
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.
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 …
good article.. eagerly looking forward to Java 8 Lambda.. 🙂
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!