Возвращаемое значение метода по умолчанию в интерфейсах Java - PullRequest
15 голосов
/ 29 сентября 2010

При работе с аннотациями я наткнулся на следующий фрагмент кода (это аннотация 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 специфичным для аннотации?И если да, что говорит против использования этой конструкции в нормальных определениях интерфейса?

Ответы [ 2 ]

21 голосов
/ 29 сентября 2010

Java 8 и далее

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

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

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

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

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

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

public abstract class DefaultTest {

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

}
6 голосов
/ 24 апреля 2015

Ключевое слово по умолчанию здесь не относится к аннотациям. Это особенность Java для обеспечения реализации по умолчанию для методов интерфейса.

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

interface Vehicle {
  void speed();

  ... 
  //other interface methods
} 

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

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

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

interface Vehicle {
  void speed();

  ...
  //other interface methods

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

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

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

...