Java 中 interface 和 @interface

1、概览

本文将带你了解 Java 中 interface(接口)和 @interface(注解接口)的区别以及它们的应用。

interface是一个类实现的规范。在最常见的形式中,它是一组相关方法,这些方法没有具体的实现。

@interface 则允许你在代码中添加元数据。编译器、工具或框架使用这些元数据来影响类的行为或处理过程。

2、interface

interface 是一种规范。它规定了实现类必须实现的行为,但没有规定如何实现。它表明,任何实现接口的类都必须为接口的所有方法提供具体的实现。

public interface Animal {
    String eat();
    String sleep();
}

public class Dog implements Animal {
    @Override
    public String eat() {
        return "Dog is eating";
    }

    @Override
    public String sleep() {
        return "Dog is sleeping";
    }
}

接口的所有方法都是默认 publicabstract 的(default 方法和 static 方法除外),所有字段都是 publicstaticfinal 的。在 Java 中,我们可以使用接口实现抽象、多重继承和松散耦合。

抽象:接口只定义了调用方法所需的基本信息,而实现方法的复杂性则被隐藏起来。

多重继承:一个类可以实现多个接口,从而避免了在允许类多重继承的语言中可能出现的 “菱形继承” 问题。

松耦合:接口在功能和实现细节之间提供了明显的分离。由于我们对方法和签名进行了单独定义,它使一个类可以改变其内部流程,而不影响其用户。

3、@interface

在Java中,我们使用 @interface 来声明注解类型。注解提供了一种向 Java 代码元素(如类、方法和字段)添加元数据的方式。因此,工具和库可以利用这些元数据在编译过程或运行时收集信息,以进行代码处理。

创建一个 @Review 自定义注解,用来跟踪谁在何时审查了一段代码:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Review {
    String reviewer();
    String date() default "";
}

注意,在使用 @interface 定义 Review 注解时,我们将其定义为常规接口。我们有使用原始数据类型甚至数组的方法名和返回类型。但是,不能使用复杂对象作为返回类型

此外,还需要在使用 Review 注解时为上述所有定义的属性提供值。有一种方法可以在声明时定义默认值。如果我们并不总是需要在使用注解时提供的值,我们可以使用它。

另外,还有一点需要注意,那就是 @interface 定义上方的 @Retention@Target 注解。@Retention(RetentionPolicy.SOURCE) 注解使我们的注解在源代码中可用(运行时会被擦除)。@Target({ElementType.METHOD}) 注解指定 Review 注解将只应用于 Java 类中的方法。

现在,在 Service 方法中使用 @Review 注解:

@Review(reviewer = "Natasha", date = "2024-08-24")
public String service() {
    return "Some logic here";
}

4、对比

对比 interface @interface
目的 用于定义类可以实现的规范。 用于定义自定义注解。
内容 没有实现的方法签名、默认方法、静态方法和常量。 提供元数据的注解方法。@Retention: 指定注解的保留策略。@Target: 指定注解类型适用的元素。
用法 通过类来实现,以提供特定的行为。 用于注解代码元素(类、方法、字段等),以提供元数据。
用例 为了实现抽象,Java 中采用了多重继承,并将方法与其实现解耦。 定义自定义注解,为支持代码文档、配置、代码生成和验证的框架提供元数据。

5、总结

本文介绍了 Java 中 interface@interface 之间的区别和应用场景,它们在 Java 编程中扮演着不同的角色。interface 是关于定义类型和规范的。而 @interface 则是用于向编译器或运行时提供元数据。


Ref:https://www.baeldung.com/java-interface-vs-annotation