Java反射获取注解中Class属性需先获取注解实例再调用对应方法,支持Class<?>、Class<String>等类型,但泛型信息在运行时被擦除,仅能获得原始Class对象。

Java 中通过反射获取注解里定义的 Class 类型属性,核心是先获取注解实例,再调用其对应的方法(该方法返回 Class 对象)。只要注解中声明了 Class 类型的元素,并在目标类/方法/字段上正确使用,就能安全读取。
确认注解定义支持 Class 类型属性
注解中必须显式声明一个返回 Class 的方法(不能是 Class<?> 以外的泛型擦除形式,但 Class<?>、Class<String> 等均可):
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
Class<?> value() default Object.class;
Class<String> stringClass() default String.class;
Class[] classes() default {};
}
</font>
<H3>在目标位置使用该注解</H3>
<p>比如加在类上(也可用于方法、字段等),并传入具体的 <code>Class</code>:</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java"><img
src="https://img.php.cn/upload/skill/000/000/081/178955835420587.jpg" alt="Alibabacloud Sdk Client Initialization For Java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java">Alibabacloud Sdk Client Initialization For Java</a>
<p>在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。</p>
</div>
<a href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>
<font color="gray">
<pre class="brush:php;toolbar:false;">
@MyAnnotation(value = List.class, stringClass = Integer.class)
public class UserService {
}
</font>
<H3>通过反射读取 Class 属性值</H3>
<p>获取类对象后,拿到注解实例,直接调用方法即可。注意:返回值就是运行时真实的 <code>Class</code> 对象,可直接用于 newInstance、isAssignableFrom、getDeclaredMethods 等操作:</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/c1c2c2ed740f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Java免费学习笔记(深入)</a></a>”;</p>
<ul>
<li>获取单个 <code>Class</code> 属性:<code>annotation.value()</code> 或 <code>annotation.stringClass()</code></li>
<li>获取 <code>Class[]</code> 数组:<code>annotation.classes()</code>,遍历每个元素都是 <code>Class</code></li>
<li>确保注解保留策略为 <code>RUNTIME</code>,否则反射无法读取</li>
<li>调用前建议判空或捕获 <code>NullPointerException</code>(若注解未添加到目标上,<code>getAnnotation()</code> 返回 null)</li>
</ul>
<font color="gray">
<pre class="brush:php;toolbar:false;">
Class<?> clazz = UserService.class;
MyAnnotation ann = clazz.getAnnotation(MyAnnotation.class);
if (ann != null) {
Class<?> valueClass = ann.value(); // → List.class
Class<String> strClass = ann.stringClass(); // → Integer.class
Class[] classArray = ann.classes(); // → []
}
处理泛型 Class(如 Class<? extends Number>)的注意事项
Java 注解不支持带具体泛型实参的 Class 字面量(如 List<String>.class 是非法语法),所以注解中只能写原始类型或通配符形式(如 Class<? extends Number>)。反射读出来的是擦除后的 Class,即 Number.class,泛型信息在运行时不可见:
-
@MyAnnotation(value = Integer.class)→ 反射得到Integer.class,不是Class<? extends Number> - 若需保留泛型语义,应改用
Type+ 自定义解析,或借助额外字符串配置(如类名 + 泛型描述)

















