@Target(ElementType.ANNOTATION_TYPE)的工作原理问题

2022-08-31 13:33:40

Java 注解用注解进行标记,以声明可以由该注解修饰的可能的连接点。枚举的值、 、 等是清晰易懂的。@TargetTYPEFIELDMETHODElementType

问题

为什么要使用价值?带注释的批注有什么用?他们的贡献是什么?给我一个解释它是如何工作的,以及为什么我应该使用它。一些已经存在的和众所周知的使用它的例子也会很棒。@Target(ANNOTATION_TYPE)


答案 1

您可以使用带注释的注释来创建元注释,例如,请考虑在Spring中的以下用法:@Transactional

/**
 * Shortcut and more descriptive "alias" for {@code @Transactional(propagation = Propagation.MANDATORY)}.
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(propagation = Propagation.MANDATORY)
public @interface RequiresExistingTransaction {
}

当您启用Spring处理注释时,它将查找携带或任何元注释的类和方法(用 注释进行注释)。@Transactional@Transactional@Transactional

无论如何,这只是一个具体的例子,如何利用带注释的注释。我想它主要是像Spring这样的框架,使用它们是有意义的。


答案 2

注释的每个注释都称为 。这意味着,您可以定义自己的自定义批注,这些批注是将许多批注合并为一个批注以创建 。@Target(ElementType.ANNOTATION_TYPE)Meta-annotationcomposed annotations

Android世界的一个很好的例子是StringDef。

表示带批注的 String 元素表示逻辑类型,并且其值应为显式命名的常量之一。

@Retention(SOURCE)
@StringDef({POWER_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE}) 
public @interface ServicesName {}

public static final String POWER_SERVICE = "power";
public static final String WINDOW_SERVICE = "window";
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";

代码检查器将以与 相同的方式处理 和 。因此,我们可以根据需要创建任意数量的命名 's 并覆盖一组常量。 它是一种允许扩展注释使用的工具。@ServicesName@WeekDays@StringDefStringDef@Target(ElementType.ANNOTATION_TYPE)


推荐