Why is there a default method?
Java 8 is coming. Although the release period has been postponed, we are still very convinced that Lambdas expressions will be supported when it is finally released. As mentioned earlier, we have discussed a lot about this theme before, but the Lambdas expression is not the only change of game rules in Java 8.
Suppose Java 8 has been released and contains Lambda. Now you plan to use Lambda. The most obvious application scenario is to apply Lambda for each element of Collection.
List <?> List = ... list.faceach (…); // This is the Lambda code
The definition of Foreach cannot be found in java.util.list or java.util.Collection. It is usually a solution to add new methods and implementation to the relevant interfaces in JDK. However, for the release of the release, it is impossible to add a new method to the interface while not affecting existing implementation.
Therefore, if Lambda is used in Java 8, it is not possible to be used for the COLLECTION library because of forward compatibility.
For the above reasons, a new concept was introduced. The virtual extension method, which is usually the defense method, can now be added to the interface, so that the default implementation of the behavior of the statement can be provided.
Simply put, the Java interface can now implement the method. The advantage of the default method is that it can add a new default method to the interface without destroying the implementation of the interface.
In my opinion, this is not the kind of Java characteristic that will be used every day, but it can definitely use Lambda to use Lambda naturally.
The simplest example
Let's see the simplest example: an interface A, the CLAZZ class implements interface A.
Public interface a {default void foo () {system.out.println ("calling a.foo ()");} public class class class a {}The code can be compiled, even if the CLAZZ class does not implement the FOO () method. The default implementation of the FOO () method is provided in interface A.
Client code using this example:
CLAZZ CLAZZ = New Clazz (); Clazz.foo (); // Call a.foo ()
Multiple inheritance?
There is a common question: people will ask when they first hear the new features of the default method "" If a class implements two interfaces, and both interfaces define the default method with the same signature. What to do? "Let's show this solution with previous examples:
Public interface a {default void foo () {system.out.println ("calling a.foo ()"); n ("calling b.foo ( ) ");}} public class class class a, b {}This code cannot compile the following reasons:
Java: Class Clazz from Types A to B to FOO () inherits the unrelated default value
In order to repair this, in Clazz, we have to manually solve the method of rewriting the conflict:
Public Class Clazz Implements a, B {Public Void Foo () {}}} But what should we do if we want to call the default implementation method from the interface A, instead of implementing our own method? This is possible, quote the foo () in A, as shown below:
Public Class Clazz Implements a, B {Public void Foo () {a.super.foo ();}}} Now I can't be very convinced that I like this final solution. Maybe it is more concise than the realization of the default method in the signature, as declared in the first hand draft of the default method specification:
Public Class Clazz Implements a, B {Public void Foo () default a.foo;}But this does change the grammar, isn't it? It looks more like a method of an interface instead of implementation. If interface A and interface B define many default methods that conflict with each other, and I am willing to use the default method of all interface A to solve the conflict? At present, I have to resolve the conflict one after another to rewrite every pair of conflict. This may require a lot of work and writing a large number of template code.
I estimate that the method of resolving the conflict requires a lot of discussions, but it seems that the creator decides to accept the unavoidable disaster.
Real example
The real examples of the default method can be found in the early bag of JDK8. Back to the example of the collection method of the collection, we can find that in the java.lang.iterable interface, its default implementation is as follows:
@FunctionAlinterfacePublic Interface ITERABLE <T> {Iterator <T> Iterator (); DEFAULT VOID FOREACH (Consumer <? Super T> Action) ON); for (t: This) {action.acccept (t) ;}}} FOREACH uses a parameter of java.util.function.consumer function interface type, which allows us to pass a lambda expression or a method reference, as follows:
List <?> List = ... list.faceach (System.out :: Println);
Method call
Let's take a look at how the default method is actually called. If you are not familiar with this problem, then you may be interested in reading Rebel Labs about Java bytes.
From the perspective of client code, the default method is only a common virtual method. Therefore, the name should be a virtual extension method. Therefore, for a simple example of the default method as the interface, the client code will automatically call the interface at the place where the default method is called.
A clazz = new clazz (); clazz.foo (); // invokeinterface foo () Clazz Clazz = New Clazz (); Clazz.foo (); // Invokevirtual Foo ()
If the conflict of the default method has been resolved, then when we modify the default method and specify one of the interfaces, Invokespecial will specify the implementation of which interface implementation of the specific call.
Public Class Clazz Implements a, B {Public void Foo () {a.super.foo (); // Invokespecial foo ()}} The following is the output of Javap:
public void foo (); code: 0: aload_01: invokespecial #2 // interfaceMethod a.foo: / ()v4: Return: Return
As you see: Invokespecial instructions are used to call the interface method FOO (). From the perspective of bytecode, this is still a new thing, because before you can only call the method by pointing to a class (parent) instead of a super that point to a interface.
at last…
The default method is the interesting supplement to the Java language. You can see them as a bridge between Lambdas expression and JDK library. The main goal of the default expression is to evolve the standard JDK interface, and when we finally start using the Lambdas expression of Java 8, we provide us with a smooth transition experience. Who knows, maybe we will see more default methods in the API design in the future.