获取不到方法的注解

本文详细介绍了Java注解的工作原理及使用方式,包括注解如何被处理和读取,特别是不同保留策略对注解可见性的影响。通过示例代码解释了如何定义自定义注解及其属性,并展示了如何通过反射API在运行时获取这些注解。

注解是不干扰原来的代码的执行的,起到一种标识作用,让第三方的注解工具来提

取注解,来完成所需的任务。

package two.zj;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention<span style="color:#ff0000;">(</span><span style="background-color: rgb(255, 0, 0);">RetentionPolicy.RUNTIME</span><span style="color:#ff0000;">)</span>
@Target(ElementType.METHOD)
public @interface TestZJ {
	public int id() default 1;
	public String name() default "nametest";
	public String value() ;
	public abstract int [] intt();
	public abstract TestEnum[] tenum();
	
	
}

package two;


import two.zj.TestEnum;
import two.zj.TestZJ;
public class UserAnn {
<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * @param user
<span style="white-space:pre">	</span> * @return user
<span style="white-space:pre">	</span> */
<span style="white-space:pre">	</span>@TestZJ(id=22,name="liyy", intt = { 0,1,2,3 }, value = "", tenum = {TestEnum.TEST1})
<span style="white-space:pre">	</span>public User getUser(User user) {
<span style="white-space:pre">		</span>return user;
<span style="white-space:pre">	</span>}


}

package two;


import java.lang.reflect.Method;


import two.zj.TestZJ;


public class Testmain {


public static void main(String[] args) throws ClassNotFoundException {
// Class class1 = Class.forName("two.UserAnn");
Class class1 = UserAnn.class;
Method [] methods = class1.getDeclaredMethods();
for(Method method:methods){
TestZJ annotations = method.getAnnotation(TestZJ.class);
if(annotations !=null){
System.out.println(annotations.id());
}
}
}
}

当注解类TestZJ中的@Retention(RetentionPolicy.RUNTIME)   为source 或者class 时候 反射是获取不到注解类的,因为jdk用说明

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,


    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,


    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

SOURCE在编译的c字节码中去掉注解,CLASS 字节码中有注解但是不加载到虚拟机,RUNTIME可以通过反射获取到注解信息,而注解框架也是采用的这种原理。



若 Java 反射能够获取方法返回值,但无法获取注解,可从以下方面排查并解决: ### 检查注解的保留策略 注解的保留策略决定了注解在什么阶段可用。若要在运行时通过反射获取注解信息,注解的保留策略需设为 `RUNTIME`。示例如下: ```java import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; // 将注解的保留策略设置为 RUNTIME @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String value(); } class MyClass { @MyAnnotation(value = "test") public void myMethod() { // 方法体 } } public class Main { public static void main(String[] args) throws NoSuchMethodException { java.lang.reflect.Method method = MyClass.class.getMethod("myMethod"); MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); if (annotation != null) { System.out.println(annotation.value()); } } } ``` ### 检查注解是否直接声明 若要获取直接声明在元素上的注解,可使用 `getDeclaredAnnotations()` 方法;若要获取继承来的注解,需使用 `getAnnotations()` 方法。示例如下: ```java import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String value(); } class Parent { @MyAnnotation(value = "parent") public void myMethod() { // 方法体 } } class Child extends Parent { @Override public void myMethod() { // 方法体 } } public class Main { public static void main(String[] args) throws NoSuchMethodException { java.lang.reflect.Method method = Child.class.getMethod("myMethod"); // 获取所有注解,包括继承来的 MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); if (annotation != null) { System.out.println(annotation.value()); } // 获取直接声明的注解 MyAnnotation declaredAnnotation = method.getDeclaredAnnotation(MyAnnotation.class); if (declaredAnnotation != null) { System.out.println(declaredAnnotation.value()); } } } ``` ### 检查类加载器和字节码增强 某些情况下,类加载器或字节码增强工具可能会影响注解的读取。要确保类加载器正确加载类,并且字节码增强工具没有移除注解。 ### 检查注解的使用范围 要保证注解被正确应用到目标元素上。例如,若注解只能用于类,就不能将其应用到方法上。 ### 调试和日志记录 在代码里添加调试信息,输出注解相关的信息,从而帮助定位问题。示例如下: ```java import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String value(); } class MyClass { @MyAnnotation(value = "test") public void myMethod() { // 方法体 } } public class Main { public static void main(String[] args) throws NoSuchMethodException { java.lang.reflect.Method method = MyClass.class.getMethod("myMethod"); java.lang.annotation.Annotation[] annotations = method.getAnnotations(); for (java.lang.annotation.Annotation annotation : annotations) { System.out.println(annotation.annotationType().getName()); } } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值