interface MyMark {}
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
@MyAnnotation
class Parent implements MyMark {}
class Heir extends Parent {}
class Test {
public static void test(MyMark markedObject) {
// do somthing.
}
public static void testAnno(Object object) {
if(!object.getClass().isAnnotationPresent(MyAnnotation.class)) {
throw new RuntimeException("object is not annotated by MyAnnotation")
}
// do something
}
public static void main(String[] args) {
Parent parent = new Parent();
Heir heir = new Heir();
test(parent);
test(heir); // ошибок нет
testAnno(parent);
testAnno(heir); // ошибка времени исполнения.
}
}
1. 接口定义了一个类型。
接口标记实现类型的对象。因此消除了编译阶段的错误。
例子:
2. 接口定义类后代的类型
如果您指定一个类实现一个接口,那么它的所有后代都将实现它。您不能从后代中反实现接口。在这里,注解有一个优势,但是对是否存在令牌的检查被转移到运行时,这充满了错误。
例子:
结果:
如果需要标记类以确定方法是否可以获取这些类的对象,那么使用接口会更方便,因为会在编译时检测到错误。
如果您需要解析类元数据,那么注解会更加灵活并为您提供更多选择,尤其是考虑到注解可以有参数。但是,注释的分析会转移到运行时。
需要注意的是,注解机制不仅仅是类标记,因为它允许您对方法、字段、参数、构造函数、局部变量和包进行注解。但是这个话题非常广泛,超出了问题的范围。