Java8 's default method describes _java in detail

Source: Internet
Author: User

What is the default method?

After Java 8 is published, new methods can be added to the interface, but the interface can still be compatible with its implementation class. This is important because the class library you are developing may be widely used by multiple developers. Before Java 8, when an interface was published in the class library, if a new method was added to the interface, those implementations that implemented the interface would be at risk of crashing with the new version of the interface.

With Java 8, is there no such danger? The answer is in the negative.

Adding a default method to an interface may make some implementation classes unavailable.

First, let's look at the details of the default method.

In Java 8, the methods in an interface can be implemented (the static method in Java8 can also be implemented in an interface, but this is another topic). The method implemented in the interface is called the default method and is identified with the keyword default as the modifier. When a class implements an interface, it can implement a method that has already been implemented in an interface, but this is not necessary. This class inherits the default method. This is why the implementation class does not need to be changed when the interface changes.

What happens when you inherit more?

When a class implements more than one (such as two) interfaces, and these interfaces have the same default method, things become very complicated. What is the default method inherited by a class? Which one is not! In this case, the class implements the default method (before it can) by itself (directly or as a class that inherits the upper layer of the tree).

The same is true when an interface implements the default method and the other interface declares the default method as abstract. Java 8 tries to avoid ambiguous things and stay rigorous. If a method has a declaration in more than one interface, then any default implementation will not be inherited, and you'll get a compile-time error.

However, if you have compiled your class, there is no compile-time error. At this point, Java 8 is inconsistent. It has its own reasons, there are a variety of reasons, here I do not want to elaborate or in-depth discussion (because: The version has been released, the discussion time is too long, this platform has never been such a discussion).

1. If you have two interfaces, an implementation class.
2. One of the interfaces implements a default method m ().
3. Compile the interface and implementation class.
4. Modify the interface that does not contain the M () method to declare that the M () method is abstract.
5. Recompile the modified interface individually.
6. Run the implementation class.

The above case class can run normally. However, you cannot recompile with the modified interface, but you can still run with the old interface compilation. Next

1. Modify the interface that contains the abstract method m () to create a default implementation.
2. Compile the Modified interface
3. Run class: failed.
This method cannot be invoked when two interfaces provide a default implementation for the same method, unless the implementation class implements the default method (either directly or by inheriting a higher class on the tree).

However, this class is compatible. It can be loaded with a new interface, or even executed, as long as it does not invoke a method that has a default implementation in two interfaces.

Instance code:



To illustrate the above example, I created a test directory for C.java, which also has 3 subdirectories below to store I1.java and I2.java. The test directory contains the source code C.java of Class C. The base directory contains the version of the interface that can be compiled and run. I1 contains the M () method with a default implementation, and I2 does not contain any methods.

The implementation class contains the main method, so we can execute it in the test. It checks for the existence of command-line arguments so that we can easily execute tests that call M () and do not call M ().

Copy Code code as follows:

~/github/test$ Cat C.java
public class C implements I1, I2 {
public static void Main (string[] args) {
c C = new C ();
if (Args.length = = 0) {
C.M ();
}
}
}
~/github/test$ Cat Base/i1.java
Public interface I1 {
default void M () {
SYSTEM.OUT.PRINTLN ("Hello interface 1");
}
}
~/github/test$ Cat Base/i2.java
Public interface I2 {
}

Use the following command line to compile the run:

Copy Code code as follows:
~/github/test$ javac-cp.: Base C.java
~/github/test$ java-cp.: Base C
Hello interface 1

The compatible directory contains an I2 interface with an abstract method M () and an unmodified I1 interface.

Copy Code code as follows:
~/github/test$ Cat Compatible/i2.java
Public interface I2 {
void M ();
}

This cannot be used to compile Class C:
Copy Code code as follows:
~/github/test$ JAVAC-CP.: Compatible C.java
C.java:1: Error:c is isn't abstract and does not override abstract method M () in I2
public class C implements I1, I2 {
^
1 Error

The error message is very precise. Because we have the C.class of the previous compilation, if we compile the interface in the compatible directory, we will still get two interfaces that can run the implementation class:

Copy Code code as follows:

~/github/test$ Javac Compatible/i*.java
~/github/test$ JAVA-CP.: Compatible C
Hello interface 1

The third directory, called Wrong, contains the I2 interface that also defines the M () method:

Copy Code code as follows:

~/github/test$ Cat Wrong/i2.java
Public interface I2 {
default void M () {
SYSTEM.OUT.PRINTLN ("Hello Interface 2");
}
}

We should take pains to compile it. Although the M () method is defined two times, the implementation class can still run, as long as it does not invoke the method that has been defined more than once, but if we call the M () method, it will fail immediately. This is the command line argument we use:

Copy Code code as follows:

~/github/test$ Javac Wrong/*.java
~/github/test$ java-cp.: Wrong C
Exception in thread "main" java.lang.IncompatibleClassChangeError:Conflicting
Default METHODS:I1.M I2.M
At C.M (C.java)
At C.main (c.java:5)
~/github/test$ java-cp.: Wrong C X
~/github/test$

Conclusion

When you migrate a class library that adds a default implementation to the interface to the Java 8 environment, there is no problem. At least the Java8 class library developer adds the default method to the collection class. Applications that use your class library still rely on JAVA7 class libraries that do not have a default method. When you use and modify multiple libraries of different classes, there is a small chance that conflicts can occur. How can we avoid it?

Design your class library as before. Don't take it lightly when you might rely on the default method. Do not use the last resort. Choose the method name wisely to avoid conflicts with other interfaces. We will learn how to use this feature for development in Java programming.

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.