Parsing the default method in Java _java

Source: Internet
Author: User
Tags iterable

Why is there a default method?

Java 8 is coming, and although the release deadline has been postponed, we are pretty sure that it will support lambdas expressions when it is finally released. As mentioned earlier, we've talked a lot about this topic before, but the lambdas expression is not the only game rule that changed in Java 8.


Suppose that Java 8 is already published and contains a lambda. Now that you're going to use a lambda, the most obvious scenario is to apply a lambda to every element of collection.

List<?> list = ...
List.foreach (...); That's the lambda code.

The definition of foreach is not found in either the Java.util.List or the Java.util.Collection interface. The usual solution is to add new methods and implementations to the relevant interfaces in the JDK. However, for published versions, there is no way to add new methods to the interface without affecting existing implementations.

So, if you're using lambda in Java 8, how bad it would be if you couldn't use the collection library for forward compatibility reasons.


For the above reasons, a new concept has been introduced. The virtual extension method, also known as the Defender method, can now be added to the interface so that it can provide a default implementation of the declared behavior.

Simply put, the Java interface can now implement the method. The advantage of the default method is that you can add new default methods to the interface without breaking the implementation of the interface.

In my opinion, this is not the kind of Java feature that is used every day, but it definitely allows the Java Collections API to use the lambda naturally.

The simplest example

Let's look at one of the simplest examples: an interface A,clazz class implements interface A.

Public interface A {
  default void foo () {
    System.out.println ("Calling A.foo ()");
  }
 
public class Clazz implements A {
}

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.

Use the client code for this example:

Clazz clazz = new Clazz ();
Clazz.foo (); Call A.foo ()

Multiple inheritance?

There is a common problem: people will ask when they first hear about the new attributes of the default method "What if a class implements two interfaces and two interfaces define the default method with the same signature?" "Let's use the previous example to show the solution:

Public interface A {
  default void foo () {
    System.out.println ("Calling A.foo ()");
  }
 
Public interface B {
  default void foo () {
    System.out.println ("Calling B.foo ()");
  }
 
public class Clazz implements A, B {
}

This code cannot be compiled for the following reasons:

Java:class Clazz inherits the irrelevant defaults from types A through B to Foo ()

To fix this, in Clazz we had to manually resolve the method by overriding the conflict:

public class Clazz implements A, B {public
  void foo () {}
}}

But what if we want to invoke the default implementation method Foo () from interface A instead of implementing our own methods? It is possible to refer to Foo () in A, as follows:

public class Clazz implements A, B {public
  void foo () {
    a.super.foo ()
  }
}

Now I'm not quite sure I like the final plan. Perhaps it is more concise than declaring the default method's implementation in the signature, as stated in the first manuscript of the default method specification:

public class Clazz implements A, B {public
  void foo () default a.foo;
}

But it does change the syntax, doesn't it? It looks more like an interface's method declaration than an implementation. What if interface A and interface B define a number of conflicting default methods, and I would like to use the default method of all interface A to resolve conflicts? At the moment I have to resolve the conflict one after another and rewrite every method of conflict. This can take a lot of work and write a lot of template code.

I estimate that the method of resolving the conflict requires a lot of discussion, but it seems that the creator decided to accept the unavoidable disaster.

The real example

A real example of the default method implementation can be found in JDK8 's earlier packets. Back to the example of the set's Foreach method, we can see that in the Java.lang.Iterable interface, its default implementation is as follows:

@FunctionalInterface Public
interface iterable<t> {
  iterator<t> iterator ();
 
  default void ForEach (CONSUMER<? Super T> action) {
    objects.requirenonnull (action);
    for (t t:this) {
      action.accept (t);}}}

ForEach uses a parameter of the Java.util.function.Consumer function interface type, which allows us to pass in a lambda expression or a method reference, as follows:

List<?> list = ...
List.foreach (System.out::p rintln);

Method calls
Let's take a look at how the default method is actually invoked. If you are unfamiliar with this issue, then you may be interested in reading the Rebel lab report on Java bytes.

From a client-side code perspective, the default method is simply a common virtual method. So the name should be the virtual extension method. Therefore, for a simple example class that implements the default method as an interface, client code automatically invokes the interface at the place where the default method is invoked.

A clazz = new Clazz ();
Clazz.foo (); Invokeinterface foo ()
 
clazz clazz = new Clazz ();
Clazz.foo (); invokevirtual foo ()

If the default method conflict is resolved, then when we modify the default method and specify that one of the interfaces is invoked, Invokespecial will give us the implementation of which interface to call specifically.

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_0
1:invokespecial #2//Interfacemethod A.foo: () V
4:return

As you can see: The invokespecial directive is used to invoke interface method Foo (). From the point of view of the bytecode, this is still a novelty, since you can invoke the method only by pointing to a class (the parent class) rather than to the super of an interface.

At last...

The default approach is an interesting addition to the Java language – you can think of them as a bridge between lambdas expressions and JDK libraries. The primary goal of the default expression is to make the standard JDK interface evolve and provide us with a smooth transition experience when we finally start using the Java 8 lambdas expression. Who knows, maybe we'll see more of the default methods in API design in the future.

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.