Default method return value in Java interfaces

MicSim picture MicSim · Sep 29, 2010 · Viewed 26k times · Source

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?

Answer

Pace picture Pace · Sep 29, 2010

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";
  }

}