@target的作用是在编译阶段限定注解的使用位置,如@target({elementtype.method})仅允许用于方法,写错位置则编译失败;支持多位置组合及type_use、type_parameter等java 8+新增类型。

@Target 的作用不是“运行时拦截”,而是在编译阶段就明确告诉 javac:这个注解只允许出现在哪些语法位置上。写错地方,代码根本编译不过,连 class 文件都不会生成。
只允许用在方法上
用 @Target({ElementType.METHOD}) 即可。定义后:
- ✅ 允许:
@MyAnno public void save() { } - ❌ 编译报错:
@MyAnno public class Service { }(提示 “not applicable to this kind of declaration”)
注意:大括号不能省——@Target(ElementType.METHOD) 是语法错误,编译直接失败。
只允许用在类、接口或枚举上
用 @Target({ElementType.TYPE})。TYPE 涵盖三类:
- 普通类:
@MyAnno public class User { } - 接口:
@MyAnno public interface Repository { } - 枚举:
@MyAnno public enum Status { OK, ERROR }
字段、方法、参数等都不在范围内,写了也会被编译器拦下。
支持多个位置的组合写法
需要同时允许方法和类时,写成:
@Target({ElementType.METHOD, ElementType.TYPE})
- ✅ 允许:
@MyAnno public class A { }和@MyAnno public void init() { } - ❌ 仍禁止:
@MyAnno private String name;(字段未在列表中)
常见框架示例:Spring 的 @Component 是 @Target({TYPE}),@Value 是 @Target({FIELD, METHOD, PARAMETER})。
泛型与类型使用处要单独声明
如果希望注解能出现在泛型实参或类型转换等位置(如 List 或 (@Immutable Object) obj),不能只靠 METHOD 或 TYPE:
-
TYPE_USE:覆盖所有“用到类型”的地方,但不自动包含类或方法声明;需显式加上,例如
@Target({METHOD, TYPE_USE}) -
TYPE_PARAMETER:专用于泛型形参,如
class Box,必须单独列出才生效
这两个是 Java 8+ 新增,旧 JDK 下会编译失败,且反射读取方式也不同(要用 getAnnotatedXxx() 系列方法)。











