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";
    }
  • 相关阅读:
    计算机三级数据库-指导
    spring导入约束
    hibernater获取session时org.hibernate.service.spi.ServiceException错误
    springxml配置注入报错
    右键复制类的完整路径
    关于实体里的toString方法
    idea创建web项目环境
    框架快速找类
    如何在scdn博客里搜索自己博客文章
    永久消除自动产生的QQPCMgr
  • 原文地址:https://www.cnblogs.com/aston/p/10171074.html
Copyright © 2011-2022 走看看