java自定义注解中class类型成员必须声明为class或class

Java 自定义注解中定义 Class 类型的成员属性,关键在于类型写法必须合法、默认值必须合规、使用时不能传实例——它只接受 .class 字面量。
Class 成员的合法声明方式
注解中只能用 Class> 或带泛型约束的 Class extends T>,不能直接写具体类名(如 MyService)或无泛型的原始 Class。
-
Class> clazz() default Object.class;✅ 宽松但安全 -
Class extends Validator> validator() default DefaultValidator.class;✅ 推荐,体现类型意图 -
Class clazz();❌ 编译报错:Invalid type -
MyService service();❌ 非法类型,直接拒绝编译
默认值必须是 .class 字面量
Class 类型属性的 default 值只能是某个类的 .class 引用,不可为 null、不可为 new 实例、也不可省略(除非该属性不设默认值且使用时必填)。
- ✅ 正确:
Class> handler() default String.class; - ✅ 正确:
Class extends Runnable> task() default Thread.class; - ❌ 错误:
Class> handler() default null;(编译失败) - ❌ 错误:
Class> handler() default new ArrayList().getClass();(不允许运行时表达式)
使用时只能传 .class,不能传对象
在代码中应用注解时,Class 属性必须赋值为 XXX.class 形式,哪怕你手头已有该类的实例,也不能传实例本身。
- ✅ 正确:
@MyAnnotation(clazz = Integer.class) - ✅ 正确:
@MyAnnotation(validator = CustomValidator.class) - ❌ 错误:
@MyAnnotation(clazz = new Integer(42).getClass())(编译期不接受表达式) - ❌ 错误:
@MyAnnotation(clazz = someInstance.getClass())(运行时才有的值,注解需编译期确定)
运行时获取与使用 Class 属性
通过反射拿到 Class 对象后,可进一步做类型检查、实例化(需无参构造)、获取泛型信息等操作:
- 获取:
MyAnnotation ann = method.getAnnotation(MyAnnotation.class); Class> c = ann.clazz(); - 实例化(谨慎):
c.getDeclaredConstructor().newInstance()(确保有 public 无参构造) - 类型校验:
if (c.isAssignableFrom(String.class)) { ... } - 泛型提取:
if (c.getTypeParameters().length > 0) { ... }
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











