Java 8 default method will destroy your (User) Code

Source: Internet
Author: User

Java 8 default method will destroy your (User) Code

The default method of Java 8 tries to further simplify Java APIs. Unfortunately, this recent Language extension has brought about a series of complex rules, but only a few Java developers are aware of this. This article tells you why introducing the default method will damage your user's code.

At first, it seems that the default method has brought many new features to the Java Virtual Machine instruction set. In the end, the developer library can upgrade the API without causing compatibility issues with the client code. Use the default method. Any class that implements the library interface automatically adapts to the default method introduced by the interface. Once the user updates his implemented class, it is easy to use more meaningful methods to overwrite the original default method. Better, you can call the default Implementation of the interface and add business logic when overwriting the method.

So far, everything has been good. However, adding a default method when creating an interface may make Java code incompatible. This can be easily understood from the example below. Let's assume that a library requires an interface as the input:

 
 
  1. interface SimpleInput { 
  2.   void foo(); 
  3.   void bar(); 
  4.  
  5. abstract class SimpleInputAdapter implements SimpleInput { 
  6.   @Override 
  7.   public void bar() { 
  8.     // some default behavior ... 
  9.   } 

Before Java 8, similar to the method used in combination with an interface and an adapter class above, it is a very common design pattern in Java programming language. This adapter is usually provided by the database provider to save some operations on the database users. However, if the interface is provided, it is similar to allowing multiple inheritance.

We further assume that a user uses the following adapter:

 
 
  1. class MyInput extends SimpleInputAdapter { 
  2.   @Override 
  3.   public void foo() { 
  4.     // do something ... 
  5.   } 
  6.   @Override 
  7.   public void bar() { 
  8.     super.bar(); 
  9.     // do something additionally ... 
  10.   } 

In this way, we can finally interact with the database. Note how we overwrite the bar method and add additional functions for the default implementation.

What will happen if I port this library to Java 8? First, the Library is likely to discard the adapter class, and the default method is used to provide this function. Finally, the interface is in the following format:

 
 
  1. interface SimpleInput { 
  2.   void foo(); 
  3.   default void bar() { 
  4.     // some default behavior 
  5.   } 

With this new interface, you can update the code and use the default method to replace the original adapter class. The best result of using an interface instead of an adapter class is that this class can inherit extend) other classes, not specific adapters. Now let's practice it and port the MyInput class to use the default method. Because we can inherit other classes now, we inherit a third-party base class. We do not need to care about the role of this basic class here. We can assume that this is meaningful to our functions.

 
 
  1. class MyInput extends ThirdPartyBaseClass implements SimpleInput { 
  2.   @Override 
  3.   public void foo() { 
  4.     // do something ... 
  5.   } 
  6.   @Override 
  7.   public void bar() { 
  8.     SimpleInput.super.bar(); 
  9.     // do something additionally ... 
  10.   } 

To implement similar functions of the original class, we use the new Java 8 syntax to call the default method of the specified interface. At the same time, move some logic in our method to the basic class. At this point, you may pat me on the shoulder and say that this is a very good refactoring!

We have successfully used this database. However, maintenance personnel need to add another interface to provide more functions. This interface is replaced by the ComplexInput interface, which inherits from the SimpleInput interface and adds a new method. Because the default method can be safely added, the maintenance staff overwrites the default method of SimpleInput and provides a better default method. After all, this is very common for using the adapter class.

 
 
  1. interface ComplexInput extends SimpleInput { 
  2.   void qux(); 
  3.   @Override 
  4.   default void bar() { 
  5.     SimpleInput.super.bar(); 
  6.     // so complex, we need to do more ... 
  7.   } 

The new features bring very good results so that the person who maintains ThirdPartyBaseClass also decides to rely on the library. To do this, it implements the ComplexInput interface in ThirdPartyLibrary.

But what does this mean for the MyInput class? To implicitly implement the ComplexInput interface, you can inherit the ThirdPartyBaseClass class, but the default method that calls SimpleInput suddenly becomes invalid. As a result, your code cannot be compiled. Currently, this call is forbidden because Java deems that the method for calling the parent class of the parent class in a non-direct subclass is invalid. You can only call this default method in ComplexInput. However, this requires that you implement this interface in MyInput. For database users, this change is not as expected!

What's more strange is that this restriction is not imposed during Java runtime. The JVM validator allows a compiled class to call the SimpleInput: foo method. Even if the class inherits the updated ThirdPartyBaseClass, The ComplexClass is implicitly implemented. This restriction only exists in the compiler.

What can we learn from here? To put it simply, make sure that you do not overwrite the default method of the other interface in one interface, neither overwrite the default method nor overwrite the method with the abstract method. In general, use the default method with caution. Even if it makes Java's set interface API a revolutionary change easily, in essence, this method call between inheritance levels increases the complexity of the system. Before Java 7, you only need to search for the actually called code at a linear class level. This complexity is increased only when you feel it is necessary.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.