简单理解java反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在面向对象的世界里,万事万物皆对象。那么java语言中,静态成员、类是谁的对象呢?
类是对象,类是java.lang.Class类的实例对象。那么Class类的实例对象如何表示呢?我们来看一下源码:
    /*
     * Constructor. Only the Java Virtual Machine creates Class
     * objects.
     */
    private Class() {}
构造器被私有,只有java虚拟机能创建Class的实例对象。
任何一个类都是Class的实例对象,这个实例对象(类)有三种表示方式:
      Class c1 = A.class;//第一种,实际告诉我们,任何一个类都有一个隐含的静态成员变量class

      A a = new A();
      Class c2 = a.getClass();//第二种,已知该类的对象,调用getClass方法

      Class c3 = null;//第三种,通过Class.forName
      try {
    c3 = Class.forName("com.honor.A");//作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
      } catch (ClassNotFoundException e) {
    e.printStackTrace();
      }
我们可以通过类的类类型创建该类的实例对象,即通过c1、c2、c3创建A的实例对象:
        try {
          A a = c3.newInstance();//A必需要有无参数的构造方法
    } catch (InstantiationException e) {
          e.printStackTrace();
    } catch (IllegalAccessException e) {
          e.printStackTrace();
    }
Class.forName("类的全称")不仅表示了类的类型,还代表了动态加载类,编译时刻加载类是静态加载类,运行时刻加载类是动态加载类。new创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类。反射是动态加载类,反射的操作都是编译之后的操作。
反射常用的一些方法:
       c.getName();//获取类的名称
       /*
        * Method类,方法对象
        * 一个成员方法就是一个Method对象
    * getMethods方法获取所有的public修饰的函数,包括父类继承来的方法
    * getDeclaredMethods()获取的是所有该类自己声明的方法,忽略访问权限
        */
        c.getDeclaredMethods();
    Method [] methods = c.getMethods();
        for(int i = 0;i<methods.length;i++){
            Class returnType = methods[i].getReturnType();//得到方法返回值类型的类类型(int.class,String.class...)
            methods[i].getName();//得到方法的名称
        }

       /*
    * 成员变量也是对象
    * java.lang.refect.Field
    * Field类封装了关于成员变量的操作
    * getFields()方法获取的是所有的public的成员变量的信息
    * getDeclaredFields()方法获取的是该类自己声明的成员变量的信息
    *
    */
      c.getFields();
      Field [] fields = c.getDeclaredFields();
      for(Field field:fields){
          Class fieldType = field.getType();//得到成员变量的类型的类类型
          fieldType.getName();//得到成员变量类型的名字
          field.getName();//得到成员变量的名称
       }
通过反射了解集合泛型的本质:
java中集合的泛型是防止错误输入的,只在编译阶段有效,绕过编译就无效了,可以通过方法的反射来操作,绕过编译。
        List<String> list = new ArrayList<String>();
        list.add("hi");
    Class c = list.getClass();
    try {
          Method m = c.getMethod("add", Object.class);
          m.invoke(list, 10);//绕过泛型(编译)
          System.out.println(list.size());//通过list长度可以判断是否通过反射加到了list中
    } catch (Exception e) {
          e.printStackTrace();
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值