Значение возвращаемого метода метода по умолчанию в интерфейсах Java

Во время работы с аннотациями я наткнулся на следующий фрагмент кода (это аннотация Hibernate @NotNull):

@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 {};
}

Мне было интересно узнать о default ключевое слово/конструкцию в определении метода, которое я никогда раньше не видел. Как я понял, он позволяет определить значение по умолчанию для этого метода (или свойство аннотации).

Теперь я пытался применить эту конструкцию к нормальному интерфейсу, но это не удалось. Это не удалось скомпилировать:

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

Но это сработало бы:

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

Итак, мой вопрос: Является ли аннотация для ключевого слова default конкретным? И если да, то что говорит против использования этой конструкции в нормальных определениях интерфейсов?

Ответ 1

Java 8 и далее

Да, ключевое слово по умолчанию теперь можно использовать на интерфейсах. Подробнее см. Oracle docs.

Реализация немного отличается от того, о чем вы думали. Это будет:

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

Java 7 и предыдущие

Ключевое слово по умолчанию можно использовать только для аннотаций.

Если вы хотите вернуть значение по умолчанию для интерфейса, вам нужно использовать абстрактный класс.

public abstract class DefaultTest {

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

}

Ответ 2

Ключевое слово 'default' здесь не является специфичным для аннотации. Его функция java обеспечивает реализацию по умолчанию для методов интерфейса.

Необходимость такого поведения: Предположим, что первоначально интерфейс Vehicle был определен для поддержки всех функциональных методов автомобиля -

interface Vehicle {
  void speed();

  ... 
  //other interface methods
} 

Теперь классы, реализующие этот интерфейс транспортного средства, реализовали эти абстрактные методы.

Теперь в будущем автомобиль сможет летать. Поэтому вам нужно добавить и функцию летания. Теперь, если вы добавите метод flyingSpeed ​​() в интерфейс Vehicle, вам необходимо изменить все существующие классы, чтобы избежать разрыва кода. Невозможное решение.

Для обратной совместимости java предоставил функцию метода Default. Чтобы вы могли добавлять новые методы для взаимодействия с реализацией по умолчанию, поэтому существующим классам не нужно будет реализовывать этот метод. И новые классы автомобилей могут переопределять эти методы в соответствии с их потребностями.

interface Vehicle {
  void speed();

  ...
  //other interface methods

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

Используя этот способ, предыдущие существующие классы Vehicle не нуждались бы в реализации этого метода.

Для получения дополнительной информации см. здесь.