zoukankan      html  css  js  c++  java
  • Java 反射

    一切皆为对象,是Java的核心概念;

    从这个概念出发,我们不禁要问类是不是对象?如果类也是对象,类又是谁的实例对象呢?

    答案是肯定的,类也是对象,类是java.lang.Class(以下简称Class)的实例对象,Class也被成为类的类类型。

    假设有类Student,如下

    class Student{
        private int id;
        private String name;
    
        //get,set方法          
    }

    获取类的类类型有三种方法,分别如下:

    1.  Class c1 = Student.class;

    2.  Student  stu = new Student();

          Class cl = stu.getClass();

    3.  Class cl = Class.forName("类全名");

    我们可以通过类的类类型创建这个类的实例对象,前提是这个类有一个无参的构造函数,如下

    Student  stu = (Student) c1.newInstance();

    动态加载的概念

      编译时加载类是静态加载类,new 对象
      运行时加载类时动态加载类

    反射使用

    //获取类的名称
    String className = cl.getName();
    //获取类名称的简写
    String classSimpleName = cl.getSimpleName();
    
    /**
     * Method类,方法的对象
     * 一个成员方法就是一个Method对象
     * getMethods() 获取的是全部public的方法,包括从父类继承来的
     *getDeclaredMethods()获取自己声明的全部方法(public private protect),不获 
     *   取父类
     */
    Method[] methods = cl.getMethods();
    for (Method method : methods){
            //得到方法的返回类型
            //得到方法返回值的类类型
            Class returnType = method.getReturnType(); 
            //得到方法名
            String methodName = method.getName();
    
            //获取参数类型
            //得到参数列表的类型的类类型
            Class[] paras = method.getParameterTypes();
            for (Class c : paras){
                    System.out.print(c.getName());
            }
    }

    通过反射获取变量

    /**
     * 成员变量也是对象
     * java.lang.reflect.Field
     * Field 封装了成员变量的操作
     * getFields() 获取所有的public成员变量信息
     * getDeclaredFields() 获取该类自己声明的所有成员变量信息
     */
    Field[] fields = cl.getDeclaredFields();
    for (Field field : fields){
    //变量的修饰符
    //得到成员变量的类型的类类型
    Class fieldType = field.getType();
    String typeName = fieldType.getName();
    //得到成员变量的名称
    String fieldName = field.getName();
    
    //打印变量类型和变量名
    System.out.println(typeName + " " + fieldName);
    }

    打印构造函数信息

    /**
     * 构造函数也是对象
     * java.lang.reflect.Constructor 中封装了构造函数的信息
     * getConstructors() 获取所有的public的构造函数
     * getDeclaredConstructors() 获取所有的构造函数
     */
    /*Constructor[] cs = cl.getConstructors();*/
    Constructor[] cs = cl.getDeclaredConstructors();
    for (Constructor c : cs){
            //获取构造函数名称
            c.getName();
            //获取构造函数的类型的类类型
            c.getParameterTypes();
    }

    方法反射

    /**
     * 方法的反射
     * 方法的名称和方法的参数列表可以唯一确定一个方法
     * 方法的反射操作
     * Method.invoke(对象, 参数列表)
     */
    public static void main(String[] args) throws Exception{
             A a = new A();
    
             //获取print(int, int)方法
             //1. 首先获取类的类类型
             Class cl = a.getClass();
             /**
              * 2. 获取方法,名称和参数列表确定唯一方法
              * getMethod() 获取的是public方法
              * getDeclaredMethod() 获取全部自己声明的方法
              */
             Method method = cl.getMethod("print", new Class[]{int.class, int.class});
    
             //3. 方法的反射操作,是指用Method对象来进行调用
             //方法没有返回值返回null,有返回值就返回返回值
             Object object = method.invoke(a, new Object[]{1,2});
             //method.invoke(a, 1, 2);
    }

    使用反射回去对象变量值

    public static <T> void printTInfo(T t) throws IllegalAccessException{
            Class cl = t.getClass();
    
            Field[] fields = cl.getDeclaredFields();
            for (Field field : fields){
                //setAccessible(true)不总是必须的,但是变量为私有是必须设置
                field.setAccessible(true);
                System.out.println(field.get(t));
            }
    }

    使用反射解析注解

    //1.使用类加载器加载类
    Class cl = Class.forName("Student");
    //2.找到类上面的注解
    boolean exist = cl.isAnnotationPresent(Customize.class);
    
    if (exist){
            //3.拿到注解实例
            Customize customize = (Customize)                         
            cl.getAnnotation(Customize.class);
            System.out.println(customize.value());
    }
    
    //4.找到方法上的注解
    Method[] methods = cl.getMethods();
    for (Method method : methods){
            if (method.isAnnotationPresent(Customize.class)){          
                    System.out.println(((Customize)method.getAnnotation(Customize.class)).value());
            }
    }
    
    //4.1另一种解析方法
    for (Method method : methods){
           Annotation[] annotations = method.getAnnotations();
           for (Annotation annotation : annotations){
                   if (annotation instanceof Customize){
                           System.out.println(((Customize) annotation).value());
                   }
           }
    }

    注解定义

    public @interface Customize {
        String value() default "I am annotation";
    }
  • 相关阅读:
    jmeter(46) redis
    jmeter(45) tcp/ip协议
    Codeforces Round #538 (Div. 2)D(区间DP,思维)
    Codeforces Global Round 1D(DP,思维)
    Educational Codeforces Round 57D(DP,思维)
    UPC11073(DP,思维)
    Yahoo Progamming Contest 2019D(DP,思维)
    Atcoder Beginner Contest 118D(DP,完全背包,贪心)
    Xuzhou Winter Camp 1C(模拟)
    Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
  • 原文地址:https://www.cnblogs.com/aston/p/10171074.html
Copyright © 2011-2022 走看看