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

所以我的问题是:默认关键字注释是特定于的吗?如果是,那么有什么理由反对在正常的接口定义中使用此构造?


答案 1

Java 8 及更高版本

是的,现在可以在接口上使用默认关键字。有关更多详细信息,请参阅 Oracle 文档

实现与您的想法略有不同。它将是:

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

Java 7 及更早版本

默认关键字只能用于批注。

如果需要接口的默认返回值,则需要改用抽象类。

public abstract class DefaultTest {

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

}

答案 2

此处的“默认”关键字不是特定于注释的。它是java的功能,为接口方法提供默认实现。

需要这种行为 :假设最初定义了一个接口车辆来支持所有车辆功能方法 -

interface Vehicle {
  void speed();

  ... 
  //other interface methods
} 

现在,实现此 Vehicle 接口的类已经实现了这些抽象方法。

现在在未来车辆具有飞行能力。因此,您还需要添加飞行功能。现在,如果将 flyingSpeed() 方法添加到 Vehicle 接口,则需要修改所有现有类以避免中断代码。不可行的解决方案。

为了向后兼容,java提供了默认方法的功能。这样,您就可以添加新方法以使用默认实现进行交互,因此现有类不需要实现该方法。新的 Vehicle 类可以根据需要覆盖这些方法。

interface Vehicle {
  void speed();

  ...
  //other interface methods

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

使用这种方式,以前现有的 Vehicle 类不需要实现此方法。

有关详细信息,请参阅此处。