注解中获取属性值的底层原理

2020-06-24  本文已影响0人  码而优则仕

注解中获取属性值的底层原理

Java里面万物皆为对象,注解也不例外,JVM会在运行时为我们生成中间对象。

要获取JVM生成的中间对象,需要修改JVM的启动参数,才能获取到JVM为我们生成的中间对象。

JDK8配置如下命令:

JVMParamSetting.png

执行如下程序:

public class AnnotationParser {

    //解析类的注解
    public static void parseTypeAnnotation() throws Exception {
        Class target = Class.forName("com.yuns.demo.annotation.YunsCourse");
        System.out.println("=====获取类上注解=======");
        Annotation[] annotations = target.getAnnotations();
        for (Annotation annotation : annotations) {
            CourseInfoAnnotation courseInfoAnnotation = (CourseInfoAnnotation) annotation;
            System.out.println("课程名称 :" + courseInfoAnnotation.courseName());
            System.out.println("课程标签 :" + courseInfoAnnotation.courseTag());
            System.out.println("课程简介 :" + courseInfoAnnotation.courseProfile());
            System.out.println("课程序号 :" + courseInfoAnnotation.coursIendex());

        }

    }

    //解析成员变量的注解
    public static void parseFieldAnnotation() throws Exception {
        Class target = Class.forName("com.yuns.demo.annotation.YunsCourse");
        System.out.println("=====获取成员变量上的注解=======");
        Field[] fields = target.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(PersonInfoAnnotation.class)) {
                PersonInfoAnnotation personInfoAnnotation = (PersonInfoAnnotation) field.getAnnotation(PersonInfoAnnotation.class);
                System.out.println("姓名 :" + personInfoAnnotation.name());
                System.out.println("年龄 :" + personInfoAnnotation.age());
                System.out.println("精通语言 :" + personInfoAnnotation.language());
                System.out.println("性别 :" + personInfoAnnotation.gender());
            }
        }
    }

    //解析成员方法的注解
    public static void parseMethodAnnotation() throws Exception {
        Class target = Class.forName("com.yuns.demo.annotation.YunsCourse");
        System.out.println("=====获取成员方法上的注解=======");
        Method[] methods = target.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(CourseInfoAnnotation.class)) {
                CourseInfoAnnotation courseInfoAnnotation = (CourseInfoAnnotation) method.getAnnotation(CourseInfoAnnotation.class);
                System.out.println("课程名称 :" + courseInfoAnnotation.courseName());
                System.out.println("课程标签 :" + courseInfoAnnotation.courseTag());
                System.out.println("课程简介 :" + courseInfoAnnotation.courseProfile());
                System.out.println("课程序号 :" + courseInfoAnnotation.coursIendex());
            }
        }
    }


    public static void main(String args[]) throws Exception {
//        parseTypeAnnotation();
        parseFieldAnnotation();
//        parseMethodAnnotation();
    }
}

会在项目下生成com.sun.proxy文件夹,文件夹下就是JDK运行时动态代理生成的中间对象:

//实现元注解Retention
public final class $Proxy0 extends Proxy implements Retention {
    private static Method m1;
    private static Method m2;
    private static Method m4;
    private static Method m0;
    private static Method m3;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final Class annotationType() throws  {
        try {
            return (Class)super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final RetentionPolicy value() throws  {
        try {
            return (RetentionPolicy)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("java.lang.annotation.Retention").getMethod("annotationType");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m3 = Class.forName("java.lang.annotation.Retention").getMethod("value");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}
public final class $Proxy1 extends Proxy implements PersonInfoAnnotation {
    private static Method m1;
    private static Method m4;
    private static Method m3;
    private static Method m2;
    private static Method m6;
    private static Method m5;
    private static Method m7;
    private static Method m0;

public $Proxy1(InvocationHandler var1) throws  {
    super(var1);
}

public final boolean equals(Object var1) throws  {
    try {
        return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
    } catch (RuntimeException | Error var3) {
        throw var3;
    } catch (Throwable var4) {
        throw new UndeclaredThrowableException(var4);
    }
}

public final String[] language() throws  {
    try {
        return (String[])super.h.invoke(this, m4, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

public final String name() throws  {
    try {
        return (String)super.h.invoke(this, m3, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

public final String toString() throws  {
    try {
        return (String)super.h.invoke(this, m2, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

public final String gender() throws  {
    try {
        return (String)super.h.invoke(this, m6, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

public final int age() throws  {
    try {
        return (Integer)super.h.invoke(this, m5, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

public final Class annotationType() throws  {
    try {
        return (Class)super.h.invoke(this, m7, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

public final int hashCode() throws  {
    try {
        return (Integer)super.h.invoke(this, m0, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}

static {
    try {
        m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
        m4 = Class.forName("com.yuns.demo.annotation.PersonInfoAnnotation").getMethod("language");
        m3 = Class.forName("com.yuns.demo.annotation.PersonInfoAnnotation").getMethod("name");
        m2 = Class.forName("java.lang.Object").getMethod("toString");
        m6 = Class.forName("com.yuns.demo.annotation.PersonInfoAnnotation").getMethod("gender");
        m5 = Class.forName("com.yuns.demo.annotation.PersonInfoAnnotation").getMethod("age");
        m7 = Class.forName("com.yuns.demo.annotation.PersonInfoAnnotation").getMethod("annotationType");
        m0 = Class.forName("java.lang.Object").getMethod("hashCode");
    } catch (NoSuchMethodException var2) {
        throw new NoSuchMethodError(var2.getMessage());
    } catch (ClassNotFoundException var3) {
        throw new NoClassDefFoundError(var3.getMessage());
    }
}
class AnnotationInvocationHandler implements InvocationHandler, Serializable {

现在分析注解的工作原理

@CourseInfoAnnotation(courseName = "注解学习", courseTag = "基础"
        , courseProfile = "学习注解全面知识")
public class YunsCourse {

    @PersonInfoAnnotation(name = "wsq", language = {"Java", "C++"})
    private String author;


    @CourseInfoAnnotation(courseName = "Java基本知识学习", courseTag = "常识"
            , courseProfile = "学习框架必须的知识")
    public void getCourseInfo() {

    }
}
private final Map<String, Object> memberValues;
上一篇下一篇

猜你喜欢

热点阅读