25

While working with annotations I stumbled accross the following piece of code (it's the Hibernate @NotNull annotation):

@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {})
public @interface NotNull {

    @Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
    @Retention(value = RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {

        public NotNull[] value();
    }

    public String message() default "{javax.validation.constraints.NotNull.message}";

    public Class<?>[] groups() default {};

    public Class<? extends Payload>[] payload() default {};
}

I was wondering about the default keyword/construct in the method definition, which I've never seen before. As I understood, it lets you define a default value for this method (or annotation property).

Now I was trying to apply this construct to a normal interface, but it failed. This would fail to compile:

public interface DefaultTest {
    public String test() default "value";
}

But this would work:

public @interface DefaultTest {
    public String test() default "value";
}

So my question is: Is the default keyword annotation-specific? And if yes, what speaks against using this construct in normal interface definitions?

MicSim
  • 26,265
  • 16
  • 90
  • 133

3 Answers3

28

Java 8 and onwards

Yes, the default keyword can now be used on interfaces. For more details see Oracle's docs.

The implementation is slightly different than what you were thinking. It would be:

public interface DefaultTest {
    default public String test() {
        return "value";
    }
}

Java 7 and previous

The default keyword can only be used for annotations.

If you want a default return value for an interface you need to use an abstract class instead.

public abstract class DefaultTest {

  public String test() {
    return "value";
  }

}
Pace
  • 41,875
  • 13
  • 113
  • 156
  • 1
    The multiple interface inheritance makes perfect sense. Thanks for pointing this out. – MicSim Sep 29 '10 at 15:54
  • 2
    Turns out you were actually prescient. Java 8 now lets you do what you want! I've updated my answer. – Pace Apr 24 '15 at 03:49
7

The 'default' keyword here is not annotation specific. Its the feature of java to provide default implementation to interface methods.

Need of this behaviour : Suppose initially a interface Vehicle was defined to support all vehicle functional methods -

interface Vehicle {
  void speed();

  ... 
  //other interface methods
} 

Now classes implementing this Vehicle interface have implemented those abstract methods.

Now in future Vehicle have capability of flying. So you need to add flying feature as well. Now if you add flyingSpeed() method to Vehicle interface, you need to modify all the existing classes to avoid break the code. Not feasible solution.

For backward compatibility java has provided the feature of Default method. So that you can add new methods to interface with default implementation, so the existing classes would not need to implement that method. And the new Vehicle classes can override those methods as per their need.

interface Vehicle {
  void speed();

  ...
  //other interface methods

  //default method
  default void flyingSpeed() {
    System.out.println("Default flying speed");
  }
}

Using this way previous existing classes of Vehicle wouldn't need to implement this method.

For more information see here.

gtm.r
  • 101
  • 1
  • 3
0

The default keyword you referred applies specifically to annotations; used for specifying the default value of an annotation attribute ( pls see this: https://docs.oracle.com/javase/specs/jls/se12/html/jls-9.html#jls-9.6.2 ). Note that an annotation attribute can only be a primitive, String, Class, annotation, enumeration, or a 1 dimensional array of these. An interface attribute can only be declared (and by default) public static final. It's value I think must be assigned during declaration using the Java assignment syntax.

Roy Alilin
  • 107
  • 1
  • 3