What is the purpose of the default keyword in Java?

79,834

Solution 1

It's a new feature in Java 8 which allows an interface to provide an implementation. Described in Java 8 JLS-13.5.6. Interface Method Declarations which reads (in part)

Adding a default method, or changing a method from abstract to default, does not break compatibility with pre-existing binaries, but may cause an IncompatibleClassChangeError if a pre-existing binary attempts to invoke the method. This error occurs if the qualifying type, T, is a subtype of two interfaces, I and J, where both I and J declare a default method with the same signature and result, and neither I nor J is a subinterface of the other.

What's New in JDK 8 says (in part)

Default methods enable new functionality to be added to the interfaces of libraries and ensure binary compatibility with code written for older versions of those interfaces.

Solution 2

Default methods were added to Java 8 primarily to support lambda expressions. The designers (cleverly, in my view) decided to make lambdas syntax for creating anonymous implementations of an interface. But given lambdas can only implement a single method they would be limited to interfaces with a single method which would be a pretty severe restriction. Instead, default methods were added to allow more complex interfaces to be used.

If you need some convincing of the claim that default was introduced due to lambdas, note that the straw man proposal of Project Lambda, by Mark Reinhold, in 2009, mentions 'Extension methods' as a mandatory feature to be added to support lambdas.

Here's an example demonstrating the concept:

interface Operator {
    int operate(int n);
    default int inverse(int n) {
        return -operate(n);
    }
}

public int applyInverse(int n, Operator operator) {
    return operator.inverse(n);
}

applyInverse(3, n -> n * n + 7);

Very contrived I realise but should illustrate how default supports lambdas. Because inverse is a default it can easily be overriden by a implementing class if required.

Solution 3

A new concept is introduced in Java 8 called default methods. Default methods are those methods which have some default implementation and helps in evolving the interfaces without breaking the existing code. Lets look at an example:

public interface SimpleInterface {
    public void doSomeWork();

    //A default method in the interface created using "default" keyword

    default public void doSomeOtherWork() {
        System.out.println("DoSomeOtherWork implementation in the interface");
    }
}

class SimpleInterfaceImpl implements SimpleInterface {

    @Override
    public void doSomeWork() {
        System.out.println("Do Some Work implementation in the class");
    }

    /*
    * Not required to override to provide an implementation
    * for doSomeOtherWork.
    */

    public static void main(String[] args) {
        SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
        simpObj.doSomeWork();
        simpObj.doSomeOtherWork();
    }
}

and the output is:

   Do Some Work implementation in the class
   DoSomeOtherWork implementation in the interface

Solution 4

Something that was overlooked in the other answers was its role in annotations. As far back as Java 1.5, the default keyword came about as a means to provide a default value for an annotation field.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
    String value() default "AMD";
}

It usage was overloaded with the introduction of Java 8 to allow one to define a default method in interfaces.

Something else that was overlooked: the reason that the declaration default class MyClass {} is invalid is due to the way that classes are declared at all. There's no provision in the language that allows for that keyword to appear there. It does appear for interface method declarations, though.

Solution 5

Default methods in an interface allow us to add new functionality without breaking old code.

Before Java 8, if a new method was added to an interface, then all the implementation classes of that interface were bound to override that new method, even if they did not use the new functionality.

With Java 8, we can add the default implementation for the new method by using the default keyword before the method implementation.

Even with anonymous classes or functional interfaces, if we see that some code is reusable and we don’t want to define the same logic everywhere in the code, we can write default implementations of those and reuse them.

Example

public interface YourInterface {
    public void doSomeWork();

    //A default method in the interface created using "default" keyword
    default public void doSomeOtherWork(){

    System.out.println("DoSomeOtherWork implementation in the interface");
       }
    }

    class SimpleInterfaceImpl implements YourInterface{

     /*
     * Not required to override to provide an implementation
     * for doSomeOtherWork.
     */
      @Override
      public void doSomeWork() {
  System.out.println("Do Some Work implementation in the class");
   }

 /*
  * Main method
  */
 public static void main(String[] args) {
   SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
   simpObj.doSomeWork();
   simpObj.doSomeOtherWork();
      }
   }
Share:
79,834
Ravi
Author by

Ravi

Check-out my open source library : rabbitFT : It is a library for sharing file through SFTP or Sharepoint channel.

Updated on July 08, 2022

Comments

  • Ravi
    Ravi almost 2 years

    An interface in Java is similar to a class, but the body of an interface can include only abstract methods and final fields (constants).

    Recently, I saw a question, which looks like this

    interface AnInterface {
        public default void myMethod() {
            System.out.println("D");
        }
    }
    

    According to the interface definition, only abstract methods are allowed. Why does it allow me to compile the above code? What is the default keyword?

    On the other hand, when I was trying to write below code, then it says modifier default not allowed here

    default class MyClass{
    
    }
    

    instead of

    class MyClass {
    
    }
    

    Can anyone tell me the purpose of the default keyword? Is it only allowed inside an interface? How does it differ from default (no access modifier)?

    • Eran
      Eran almost 9 years
      default methods in interfaces were added in Java 8. It's not an access modifier, it's a default implementation.
    • Ravi
      Ravi almost 9 years
      @Eran don't you think, introduction of default method violating interface definition ? :s
    • Louis Wasserman
      Louis Wasserman almost 9 years
      It changed the interface definition. That definition is now out of date.
    • sprinter
      sprinter almost 9 years
      They were introduced to support lambdas. The details of why they are required are in the straw man proposal for Project Lambda.
  • Ravi
    Ravi almost 9 years
    It seems, now interface and abstract class are almost same. :)
  • Elliott Frisch
    Elliott Frisch almost 9 years
    @jWeaver They can both now provide method implementations. There's also improved type inference and lambda expressions (syntatic sugar is sweet).
  • Louis Wasserman
    Louis Wasserman almost 9 years
    @jWeaver interfaces still cannot have constructors, fields, private methods, or implementations of equals/hashCode/toString.
  • Ravi
    Ravi almost 9 years
    @LouisWasserman correct we have still some difference :) I was just telling we are getting closer to abstract class. ;)
  • ajb
    ajb almost 9 years
    @jWeaver Also, you can still have a class that implements multiple interfaces. Because of this, I think the semantics and implementation of default methods is rather different than that of concrete methods in an abstract class that don't get overridden, although I'm not sure exactly how.
  • Holger
    Holger almost 9 years
    @Louis Wasserman: In Java 9, they can have private methods.
  • Dan
    Dan almost 9 years
    @Holger wat. really? I wouldn't consider a private method to be part of the interface...
  • Holger
    Holger almost 9 years
    @Dan Pantry: private methods are not really part of the interface, but may serve as helper methods for the default implementations or within constant initializers. Note that they already exist in Java 8, as, when you use lambda expressions within interfaces, synthetic private methods are generated. So Java 9 allows you to use that feature for non-synthetic, non lambda uses as well…
  • Brian Goetz
    Brian Goetz almost 9 years
    This isn't really correct. Lambdas may be the proximate cause, but they really were just the straw that broke the camel's back. The real motivation was enabling interface evolution (allowing existing interfaces to be compatibly evolved to support new behavior); lambdas may have been the factor that brought this need to the fore, but the feature is more general than that.
  • Brian Goetz
    Brian Goetz almost 9 years
    @jWeaver The difference between interfaces and classes reduces to state vs behavior. Interfaces can carry behavior, but only classes can have state. (Fields, constructors, and methods such as equals/hashCode are about state.)
  • supercat
    supercat almost 9 years
    @BrianGoetz: IMHO, both Java and .NET would have benefited enormously had default methods existed from the get-go. If some common operation could be performed upon any implementation of an interface using only interface members, but some implementations would likely have a more efficient way of doing them, the interface should define methods for those operations and provide default implementations for them. The inability to specify default implementations has induced pressure to have interfaces omit such methods, and has made it impossible for them to add them later.
  • sprinter
    sprinter almost 9 years
    @BrianGoetz I agree default methods have significant value beyond lambdas. But I'd be interested in any reference you can give to that broader value driving the decision to include them. My reading is that lambdas were the primary reason (which is why I used the word 'primarily' in my answer).
  • Brian Goetz
    Brian Goetz almost 9 years
    Perhaps this document will help: cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.ht‌​ml. Section 10 says clearly: "The purpose of default methods (previously referred to as virtual extension methods or defender methods) is to enable interfaces to be evolved in a compatible manner after their initial publication." Lambda-friendly methods are then cited as an illustration of interface evolution.
  • chandra_cst
    chandra_cst about 8 years
    To me, it looks like Java is getting closer to the problems C++ had by allowing a class to extend from multiple base classes.
  • Ahmad Hajjar
    Ahmad Hajjar almost 8 years
    so now multiple class inheritance is possible :D ? that's being like Mixins, which is nice somehow and solves some problems, but I am not sure if it does good more than bad, or the opposite way around! Looks like the history is repeating it self again (after functional programming, now multiple classes inheritance) lol
  • Kartik
    Kartik about 5 years
    @BrianGoetz Why is the default keyword needed? If a method in an interface is not preceded by static keyword and has a body (braces as opposed to semicolon), can't we make the compiler infer that it's a default method and not an abstract or static method?
  • Brian Goetz
    Brian Goetz about 5 years
    @Kartik You are asking the wrong question! We don't choose syntax based on "what is the absolute minimum that is needed for the compiler to parse the program correctly"; we choose it on the basis of "what would make the intent of the programmer more immediately evident to readers." We design first for users, and secondarily for compilers (and when it comes to users, we design first for reading, and secondarily for writing.)
  • Geoff Langenderfer
    Geoff Langenderfer over 2 years
    We don't need to override. This is the key point. This helps me avoid editing N files with my new function. Thanks for the example!
  • navderm
    navderm about 2 years
    Question: What does that @Override annotation do when the immediate parent class is actually an interface ? Is that even required for first children of Interfaces?