注解与反射

目录

注解

1.注解入门

2.内置注解

3.自定义注解,元注解

自定义注解

元注解:对其他注解的说明

反射

1.java反射机制概述

2.理解Class类并获取Class实例

获取Class方法

 哪些类型可以有Class对象

3.类的加载与ClassLoader(这部分待定??????)

4. 什么时候发生类初始化?

以下必发生初始化

以下不会发生初始化

5.加载器

6.获取运行时类的完整结构 

7.构造对象及使用方法属性

构造对象

 有了对象,就调用方法

 操作属性

8. 分析反射性能

9.反射与泛型

10.反射与注解


注解

1.注解入门

package com.jiang.Test;

import java.util.ArrayList;
import java.util.List;

public class Test01 {
    //@Override就是注解
    //不是程序本身,但是能够对程序作出解释
    @Override
    public String toString() {
        return super.toString();
    }
    //Deprecated表示不推荐程序员使用,存在更好的方式
    @Deprecated
    public static void test(){
        System.out.println("Deprecated");
    }

    public static void main(String[] args) {
        test();//有一条线划掉
    }

    @SuppressWarnings("all")
    //抑制编译时的警告信息(灰色字体),可以放在类上
    public void test02(){
        List list=new ArrayList();//list存在!警告
    }

2.内置注解

  • @Override
  • @Deprecated 表示不推荐程序员使用,使用时会存在一条横线
  • @SuppressWarnings("all") 抑制编译时警告,灰色字体

3.自定义注解,元注解

自定义注解

package com.jiang.Test;

import java.lang.annotation.*;

public class Test02 {
    @MyAnnotation
    public void test(){}
}

@Target(ElementType.METHOD)
//定义一个注解
//表示注解在什么地方还有效
//runtime》 class 》 source
@Retention(RetentionPolicy.RUNTIME)
@Documented
//表示是否将我们的注解生成在JAVADOC中
@Inherited
//子类可以继承父类的注解
@interface MyAnnotation{

}

 可以设置value和默认值

package com.jiang.Test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

public class Test03 {
    @annotation(name = "ddd")
    public void test(){}
}


@Target({ElementType.TYPE,ElementType.METHOD})
@interface annotation {
    //注解参数   默认值
    String name() default "";
}

元注解:对其他注解的说明

  • @Target(适用范围ElementType.METHOD方法,ElementType.TYPE类,ElementType.FIELD属性)
    @Retention(什么级别保存该注释,一般都是RunTime, source > class >runtime) 
    @Document(表示是否将我们的注解生成在JAVADOC中)
    @Inherited(可以继承父类的注解)

反射

1.java反射机制概述

根据对象找类 =》反射

2.理解Class类并获取Class实例

多个对象,一个Class

package com.jiang.Test.Reflect;


//反射机制允许程序在执行期借助API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
//Class c =Class.forName("java.lang.String")
public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射机制获取Class对象
        Class<?> aClass = Class.forName("com.jiang.Test.Reflect.user");
        System.out.println(aClass);
        Class<?> bClass = Class.forName("com.jiang.Test.Reflect.user");
        Class<?> cClass = Class.forName("com.jiang.Test.Reflect.user");
        System.out.println(bClass.hashCode());
        System.out.println(cClass.hashCode());
        //结果都相同,说明是类是相同的
        //一个类在内存中只有一个Class对象
        //一个类被加载后,类的整个结构都会被封装在class对象中
        //对象求出类==》 反射
        user user=new user();
        System.out.println(user.getClass());
    }
}
class user{
    public user() {
    }

    private String ID;
    private String name;
    public int age;

    public user(String ID, String name, int age) {
        this.ID = ID;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "user{" +
                "ID='" + ID + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 一个类在内存中只有一个Class

类被加载到内存中,其整个结构都会被封装在Class对象中

获取Class方法

  • 对象获得
  • forname
  • 类名.class属性
  • 获取父类类型:getSupperClass()
package com.jiang.Test.Reflect;

public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person=new Student();
        System.out.println(person.name);

        //测试Class类的创建方式有哪些?
        //方式一:通过对象获得
        Class<? extends Person> aClass1 = person.getClass();
        System.out.println(aClass1.hashCode());

        Person person1=new Person();
        System.out.println(person1.getClass());
        Student student =new Student();
        System.out.println(student.getClass());

        //方式二:forname
        Class<?> aClass = Class.forName("com.jiang.Test.Reflect.Student");
        System.out.println(aClass.hashCode());

        //方式三:通过类名获得
        Class<Student> studentClass = Student.class;
        System.out.println(studentClass.hashCode());

        //获得父类类型(先获取子Class才能获得父Class)
        System.out.println(studentClass.getSuperclass());
    }
}

class Person{
    public String name;

    Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }

    public Person(String name) {
        this.name = name;
    }
}
class Student extends Person{
    public Student(){
        this.name="学生";
    }
}

 哪些类型可以有Class对象

package com.jiang.Test.Reflect;

import java.lang.annotation.ElementType;

public class Test03 {
    public static void main(String[] args) {
        //所有类型的Class
        System.out.println(Object.class);
        System.out.println(Comparable.class);//接口
        System.out.println(String[].class);
        System.out.println(int[][].class);
        System.out.println(Override.class);//注解
        System.out.println(ElementType.class);//枚举
        System.out.println(Integer.class);
        System.out.println(void.class);
        System.out.println(Class.class);


        //不管你多长,都是这个类型
        int[] a=new int[10];
        int[] b=new int[100];
        int[] c=new int[]{10,100};
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
        System.out.println(c.getClass().hashCode());
    }
}

3.类的加载与ClassLoader(这部分待定??????)

加载

将class文件字节码加载到内存中,并将静态数据放入方法区,然后生成一个代表这个类的java.lang.Class对象

链接

  • 验证
  • 准备 分配类存设置初始值
  • 解析

初始化

static拼接在一起 

package com.jiang.Test.Reflect;

//java内存分析
/*堆  存放对象和数组
* 栈  存放基本数据类型,变量
  方法区 所有的class和static变量
 * */


/*
类加载过程:
类加载  --》 类的链接  --》类的初始化
将class文件读入内存并创建Class对象
将类的二进制数合并到JRE中
JVM负责对类进行初始化
 */
public class Test04 {
    public static void main(String[] args) {
        A a=new A();
    }

}
class A{
    static {
        System.out.println("A类静态代码初始化");
        m=300;
    }
    static int m=100;

    public A(){
        System.out.println("A类的无参构造初始化");
    }
}

4. 什么时候发生类初始化?

以下必发生初始化

  • 主动引用
  • 反射
  • 调用类的静态成员和方法
  • 初始化子类,父类也会跟着初始化

以下不会发生初始化

  • 访问静态域,只会初始化静态域所在类
  • 数组定义引用,不会触发此类初始化
  • 调用常量池和final
package com.jiang.Test.Reflect;

public class Test05 {
    static {
        System.out.println("Main类被加载");
    }
    public static void main(String[] args) throws ClassNotFoundException {
        //1、主动引用(一定发生类的初始化)
        //Son son=new Son();
        //Main类被加载
        //        父类被加载
        //子类被加载
        //2、反射也会产生主动引用
        //Class.forName("com.jiang.Test.Reflect.Son");
        //Main类被加载
        //        父类被加载
        //子类被加载
        //3.调用类的静态成员和方法
        //System.out.println(Son.son);
        //Main类被加载
        //        父类被加载
        //子类被加载
        //5
        //final不会被加载
        //System.out.println(Son.M);
        //Main类被加载
        //1


        //被动引用(不会发生类的初始化)
        //1.访问静态域,只会初始化声明该静态域的类。
        //System.out.println(Son.father);
        //Main类被加载
        //        父类被加载
        //10
        //2.数组定义引用,不会触发此类的初始化
        //Son[] sons=new Son[10];
        //Main类被加载
        //3.调用常量池不会被初始化(常量在链接阶段就存入调用类的常量池中了)
        System.out.println(Son.M);
        //Main类被加载
        //1

    }
}

class Father{
    static int father=10;
    static {
        System.out.println("父类被加载");
    }
}
class Son extends Father{
    static int son=5;
    static {
        System.out.println("子类被加载");
        m=300;
    }
    static int m=100;
    static final int M=1;
}

 

 

 

5.加载器

  • 系统类的加载器
  • 扩展类加载器
  • 根加载器
package com.jiang.Test.Reflect;

public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类的加载器
        System.out.println(ClassLoader.getSystemClassLoader());

        //获取系统类加载器的父类加载器--》 扩展类加载器
        System.out.println(ClassLoader.getSystemClassLoader().getParent());

        //扩展类加载器的父类 --》根加载器
        System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());

        System.out.println(Class.forName("com.jiang.Test.Reflect.Test06").getClassLoader());

        System.out.println(Class.forName("java.lang.Object").getClassLoader());

        //获得系统类加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));
        //C:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;
        // C:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;
        // C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;
        // C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;
        // C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;D:\IDEA_Project\Annotataion_Reflect\out\production\Annotataion_Reflect;D:\IDEA\IntelliJ IDEA 2020.3.3\lib\idea_rt.jar

    }
}

6.获取运行时类的完整结构 

  1. declare是所有包括私有
  2. getname(整个包名)getsimplename(类名)
  3. 用Class去获取对象结构
  • 获取属性
  • 获取指定属性
    user.getClass().getField("age")
  • 获取所有public方法
  • 获取所有方法
  • 获取指定方法(无参、有参)
    user.getClass().getMethod("getName", null) 无参
    user.getClass().getMethod("setName", String.class) 有参
  • 获取构造器
  • 获取指定构造器
    user.getClass().getConstructor(String.class, String.class, int.class)

package com.jiang.Test.Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test07 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        user user = new user();
        System.out.println(user.getClass());
        System.out.println(user.getClass().getName());
        System.out.println(user.getClass().getSimpleName());

        //属性
        Field[] fields = user.getClass().getFields();//public
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("===================");//all
        Field[] declaredFields = user.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        System.out.println("===================");
        //指定属性
        System.out.println(user.getClass().getField("age"));
        System.out.println("===================");

        //获得本类及其父类的所有public方法
        Method[] methods = user.getClass().getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("===================");

        //获取本类所有方法
        Method[] declaredMethods = user.getClass().getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("===================");
        //获取指定方法
        System.out.println(user.getClass().getMethod("getName", null));
        System.out.println(user.getClass().getMethod("setName", String.class));

        //获取构造器
        System.out.println("===================");
        Constructor<?>[] constructors = user.getClass().getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }

        Constructor<?>[] declaredConstructors = user.getClass().getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        //获得指定的构造器
        System.out.println(user.getClass().getConstructor(String.class, String.class, int.class));
    }
}

class user{
    public user() {
    }

    private String ID;
    private String name;
    public int age;

    public user(String ID, String name, int age) {
        this.ID = ID;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "user{" +
                "ID='" + ID + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

7.构造对象及使用方法属性

构造对象

1.无参

本质上是调用了user的无参构造,当无参构造消失则会报错

aClass.newInstance()

2.有参

先获取有参构造器,然后构造器初始化传参

 Constructor<?> constructor = aClass.getConstructor(String.class, String.class, int.class);
        Object o1 = constructor.newInstance("20380402117", "蒋镕", 11);

 有了对象,就调用方法

获取指定参数方法,invoke激活方法。o1激活setname(“更名”)

    Method setName = aClass.getDeclaredMethod("setName", String.class);

        //invoke:激活的意思
        setName.invoke(o1,"更名");

 操作属性

有安全监测,操作私有会报错

  Field name = aClass.getDeclaredField("name");
        name.set(o1,"属性");
        System.out.println(o1);
        报错 权限受限
        can not access a member of class com.jiang.Test.Reflect.user with modifiers "private"
    

 调用setAccessible(true)关闭监测机制

   Field name2 = aClass.getDeclaredField("name");
        name2.setAccessible(true);//关闭权限检查 关闭安全监测
        //方法、属性、构造器都有一个安全监测机制
        name2.set(o1,"属性");
        System.out.println(o1);
package com.jiang.Test.Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> aClass = Class.forName("com.jiang.Test.Reflect.user");

        //构造对象
        Object o = aClass.newInstance();//本质上是调用了user的无参构造,当无参构造消失则会报错
        user user=(user) o;
        System.out.println(user);

        //构造对象,有参
        //获取构造器
        Constructor<?> constructor = aClass.getConstructor(String.class, String.class, int.class);
        Object o1 = constructor.newInstance("20", "李四", 11);
        System.out.println(o1);


        //有了对象自然就想着调用方法
        //通过反射调用普通方法
        Method setName = aClass.getDeclaredMethod("setName", String.class);

        //invoke:激活的意思
        setName.invoke(o1,"更名");
        System.out.println(o1);

        //通过反射操作属性

        //Field name = aClass.getDeclaredField("name");
        //name.set(o1,"属性");
        //System.out.println(o1);
        //报错 权限受限
        //can not access a member of class com.jiang.Test.Reflect.user with modifiers "private"
        Field name2 = aClass.getDeclaredField("name");
        name2.setAccessible(true);//关闭权限检查 关闭安全监测
        //方法、属性、构造器都有一个安全监测机制
        name2.set(o1,"属性");
        System.out.println(o1);
    }
}
"C:\Program Files\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:D:\IDEA\IntelliJ IDEA 2020.3.3\lib\idea_rt.jar=57461:D:\IDEA\IntelliJ IDEA 2020.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;D:\IDEA_Project\Annotataion_Reflect\out\production\Annotataion_Reflect" com.jiang.Test.Reflect.Test09
user{ID='null', name='null', age=0}
user{ID='20', name='李四', age=11}
user{ID='20', name='更名', age=11}
user{ID='20', name='属性', age=11}

Process finished with exit code 0

8. 分析反射性能

多次调用getName()方法,计算时间,比较属性

  • 普通
  • 反射
  • 反射关闭监测
package com.jiang.Test.Reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//分子性能问题
public class Test10 {
    public static void test01(){
        user user=new user();
        long start=System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            user.getName();
        }
        long end=System.currentTimeMillis();
        System.out.println("普通方法时间:"+(end-start));
    }

    public static void test02() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<?> aClass = Class.forName("com.jiang.Test.Reflect.user");
        Method getName = aClass.getMethod("getName", null);

        long start=System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            getName.invoke(new user(),null);
        }
        long end=System.currentTimeMillis();
        System.out.println("反射方法时间:"+(end-start));
    }
    public static void test03() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<?> aClass = Class.forName("com.jiang.Test.Reflect.user");
        Method getName = aClass.getMethod("getName", null);
        getName.setAccessible(true);
        long start=System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            getName.invoke(new user(),null);
        }
        long end=System.currentTimeMillis();
        System.out.println("关闭安全监测反射方法时间:"+(end-start));
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test01();
        test02();
        test03();
        //普通方法时间:6
        //反射方法时间:315
        //关闭安全监测反射方法时间:202

    }
}

9.反射与泛型

  • 获取泛型方法的参数
Type[] genericParameterTypes = test1.getGenericParameterTypes();

java.util.Map<java.lang.String, com.jiang.Test.Reflect.user> java.util.List<com.jiang.Test.Reflect.user>

  • 获取泛型方法参数的参数
 if (genericParameterType instanceof ParameterizedType){
                //获取真实类型
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }

 class java.lang.String
class com.jiang.Test.Reflect.user

class com.jiang.Test.Reflect.user

  • 无参泛型,返回值是泛型

        Method test2 = Test11.class.getMethod("test2", null);
        Type genericReturnType = test2.getGenericReturnType();
        System.out.println(genericReturnType);
        if (genericReturnType instanceof  ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }

 java.util.Map<java.lang.String, com.jiang.Test.Reflect.user>
class java.lang.String
class com.jiang.Test.Reflect.user

package com.jiang.Test.Reflect;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Test11 {
    public void test1(Map<String,user> map, List<user> list){
        System.out.println("test1");
    }

    public Map<String,user> test2(){
        System.out.println("test2");
        return null;
    }
    public static void main(String[] args) throws NoSuchMethodException {
        //获取泛型方法的参数
        Method test1 = Test11.class.getMethod("test1", Map.class, List.class);
        Type[] genericParameterTypes = test1.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println(genericParameterType);
            //java.util.Map<java.lang.String, com.jiang.Test.Reflect.user>
            //java.util.List<com.jiang.Test.Reflect.user>
            //想把里面的string user输出来
            if (genericParameterType instanceof ParameterizedType){
                //获取真实类型
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }
        System.out.println("-----------");
        Method test2 = Test11.class.getMethod("test2", null);
        Type genericReturnType = test2.getGenericReturnType();
        System.out.println(genericReturnType);
        if (genericReturnType instanceof  ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
    }
}
"C:\Program Files\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:D:\IDEA\IntelliJ IDEA 2020.3.3\lib\idea_rt.jar=57887:D:\IDEA\IntelliJ IDEA 2020.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;D:\IDEA_Project\Annotataion_Reflect\out\production\Annotataion_Reflect" com.jiang.Test.Reflect.Test11
java.util.Map<java.lang.String, com.jiang.Test.Reflect.user>
class java.lang.String
class com.jiang.Test.Reflect.user
java.util.List<com.jiang.Test.Reflect.user>
class com.jiang.Test.Reflect.user
-----------
java.util.Map<java.lang.String, com.jiang.Test.Reflect.user>
class java.lang.String
class com.jiang.Test.Reflect.user

10.反射与注解

  • 获取类注解
 Annotation[] annotations = aClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
            //@com.jiang.Test.Reflect.table(value=db_student)
        }
  • 获取类注解的值

annotation.value() -- 自定义的参数名

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface  table{
    String value();
}
   //获得注解value的值
        table annotation = aClass.getAnnotation(table.class);//@com.jiang.Test.Reflect.table(value=db_student)
        String value = annotation.value();
        System.out.println(value);//db_student
  •  获取指定属性注解及值
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface field{
    String columname();
    String type();
    int length();
}
//获得字段注解的值
        //获得属性
        Field id = aClass.getDeclaredField("id");
        field annotation1 = id.getAnnotation(field.class);
//@com.jiang.Test.Reflect.field(columname=db_id, type=int, length=10)
        System.out.println(annotation1);
        System.out.println(annotation1.columname());
        System.out.println(annotation1.type());
        System.out.println(annotation1.length());
package com.jiang.Test.Reflect;

import java.lang.annotation.*;
import java.lang.reflect.Field;

//ORM Object relationship Mapping 对象关系映射
//反射操作注解
public class Test12 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> aClass = Class.forName("com.jiang.Test.Reflect.student2");

        //获取注解
        Annotation[] annotations = aClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
            //@com.jiang.Test.Reflect.table(value=db_student)
        }
        //获得注解value的值
        table annotation = aClass.getAnnotation(table.class);
        String value = annotation.value();
        System.out.println(value);//db_student

        //获得字段注解的值
        //获得属性
        Field id = aClass.getDeclaredField("id");
        field annotation1 = id.getAnnotation(field.class);
        System.out.println(annotation1);
        System.out.println(annotation1.columname());
        System.out.println(annotation1.type());
        System.out.println(annotation1.length());
    }
}

@table("db_student")
class student2{
    @field(columname = "db_id",type = "int",length = 10)
    private int id;
    @field(columname = "db_age",type = "int",length = 10)
    private int age;
    @field(columname = "db_name",type = "varchar",length = 3)
    private String name;

    public student2(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "student{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public student2() {
    }
}


//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface  table{
    String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface field{
    String columname();
    String type();
    int length();
}
@com.jiang.Test.Reflect.table(value=db_student)
db_student
@com.jiang.Test.Reflect.field(columname=db_id, type=int, length=10)
db_id
int
10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值