博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
反射 注解的解析
阅读量:6865 次
发布时间:2019-06-26

本文共 3377 字,大约阅读时间需要 11 分钟。

hot3.png

自定义注解 (只可以解析RUNTIME的才有效果)

  1. 只有一个成员的注解
public @interface Description{    String desc();}@Description(desc="the name method")

不会报错。 但不符合规范,既然只有一个成员,就要使用value作为成员名,改成:

public @interface Description{    String value();}

然后在使用注解的时候,直接赋值,不写成员名和等号:

@Description("the name method")

以上方式,约定俗成,比较直观。

  1. 没有成员的注解——标志注解(比如常见的@Override),在使用的时候不加括号。
  2. 当一个方法被规定为({ElementType.METHOD})就表示只能用于方法的注解,如果用在类上面,就会报错(添加 ElementType.TYPE 则可适用于类)。这里没有包含关系,例如只写ElementType.TYPE 则不能对方法进行注解,只能对类或接口进行注解。
  3. @Documented(属于标识注解,生成javadoc时会包含注解) 创建一个Javadoc :右击项目--> Export --> Java --> Javadoc --> next -->Browser 选择要存放的文件夹。点击finish就生成成功了。 打开这个文件夹,点击index.html,就能查看该项目的一些摘要。
package com.test;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME)@Inherited @Documentedpublic @interface Boy {    //public String name(String name);//这是错误的    //注解的方法不可带参数    //注解的方法叫做成员    public String name();    //public Object jump();    //注解方法返回值类型限定为:基本类型、String、Enums、Annotation或者是这些类型的数组;    public int  jump();    //注解方法可以有默认值;    public int age() default 18;}

使用自定义注解语法

@<注解名>(<成员名1>=<成员的值1>,<成员名2>=<成员的值2>,)

@Boy(name="king",age=20)public String User(){        return "user";}

解析注解

概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

isAnnotationPresent() getAnnotation() getAnnotations() 类上的注解,方法上班的注解

1.定义了一个Boy注解

package com.test;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)@Inherited @Documentedpublic @interface Boy {    public String name();    public int age() default 18;}

定义了一个使用Boy注解的Student

package com.test;@Boy(name="king",age=20)public class Student {        @Boy(name="kk",age=25)    public String user() {                return "ddd";    }}

解析Student上的boy注解

package com.test;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class Test {    public static void main(String[] args) throws ClassNotFoundException {                //1.使用类加载器加载类            Class c = Class.forName("com.test.Student");        //2.找到类上的注解        boolean isExist = c.isAnnotationPresent(Boy.class);                if(isExist){         //3.拿到注解实例        Boy d = (Boy)c.getAnnotation(Boy.class);        //访问直接成员的值        System.out.println(d.name());        System.out.println(d.age());        }                //4.找到方法上的注解        Method[] ms = c.getMethods();        for(Method m:ms){                boolean isMExist = m.isAnnotationPresent(Boy.class);                if(isMExist){                    Boy d = m.getAnnotation(Boy.class);                    System.out.println(d.name());                    System.out.println(d.age());                }                  }                    }}

getAnnotations()

for(Method m:ms){Annotation[] as = m.getAnnotations();for(Annotation a:as){if(a instanceof Boy){Boy d = (Boy)a; System.out.println(d.name()); System.out.println(d.age());}

@Inherited

如果子类继承 只会继承class上的注解,不会继承方法上的注解

转载于:https://my.oschina.net/2016jyh/blog/1789102

你可能感兴趣的文章