Значение возвращаемого метода метода по умолчанию в интерфейсах 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 не нуждались бы в реализации этого метода.
Для получения дополнительной информации см. здесь.