zoukankan      html  css  js  c++  java
  • java反射的原理,作用

    什么是反射,反射原理

      java类的执行需要经历以下过程

        编译:.java文件编译后生成.class字节码文件
        加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例
        连接:细分三步
            验证:格式(class文件规范) 语义(final类是否有子类) 操作
            准备:静态变量赋初值和内存空间,final修饰的内存空间直接赋原值,此处不是用户指定的初值。
            解析:符号引用转化为直接引用,分配地址
        初始化:有父类先初始化父类,然后初始化自己;将static修饰代码执行一遍,如果是静态变量,则用用户指定值覆盖原有初值;如果是代码块,则执行一遍操作。

    什么是反射:

      Java的反射就是利用上面第二步加载到jvm中的.class文件来进行操作的。.class文件中包含java类的所有信息,当你不知道某个类具体信息时,可以使用反射获取class,然后进行各种操作。

      Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性

    要想解剖一个类,必须先要获取到该类的字节码文件对象(class)。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.)

    关于class对象和这个Class类

    • Class对象的由来是将class文件读入内存,并为之创建一个Class对象

        

     Class类

      class类 :代表一个类,是Java反射机制的起源和入口

      用于获取与类相关的各种信息, 提供了获取类信息的相关方法
      Class类继承自Object类

      Class类是所有类的共同的图纸

      每个类有自己的对象,同时每个类也看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应的信息:类的名字、属性、方法、构造方法、父类和接口。

    获取class对象(反射入口)的三种方式

      要想操作反射,必须先拿到反射的入口

      1,通过通过Class.forName("全类名") 静态方法来获取,用的最多 

        Class c3 = Class.forName("reflect_fanshe.Person");
    Class<?> perClazz = Class.forName("reflect_fanshe.Person");

      2,类名.class

        /2、类名.class 的方式得到,该方法最为安全可靠,程序性能更高
        //  这说明任何一个类都有一个隐含的静态成员变量 class
        Class c2 = Person.class;

    Class<?> perClazz2 = Person.class;

      3,对象.getClass()

    Person person = new Person();
    Class<?> perClazz3 = person.getClass();

    Class具有的部分方法如下:     

         getName():获得类的完整名字。
      getFields():获得类的public类型的属性
      getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
      getMethods():获得类的public类型的方法。
      getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
      getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
      getConstructors():获得类的public类型的构造方法。
      getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
      newInstance():通过类的不带参数的构造方法创建这个类的一个对象

    通过反射获取对象的实例,并操作对象

      1,class.newInstance() ,并强转类型,然后就可以操作对象了,主要是调用方法。

        

       

      2,操作属性,可以操作类里面的public属性和private属性  如果属性是private,正常情况下是不允许外界操作属性值,这里可以用Field类的setAccessible(true)方法,暂时打开操作的权限

           

    反射方法的使用之---通过反射运行配置文件内容

      student类:

    public class Student {
        public void show(){
            System.out.println("is show()");
        }
    }

      配置文件以txt文件为例子(pro.txt):

    className = cn.fanshe.Student
    methodName = show

      测试类:

    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.Properties;
     
    /*
     * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改
     * 我们只需要将新类发送给客户端,并修改配置文件即可
     */
    public class Demo {
        public static void main(String[] args) throws Exception {
            //通过反射获取Class对象
            Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"
            //2获取show()方法
            Method m = stuClass.getMethod(getValue("methodName"));//show
            //3.调用show()方法
            m.invoke(stuClass.getConstructor().newInstance());
            
        }
        
        //此方法接收一个key,在配置文件中获取相应的value
        public static String getValue(String key) throws IOException{
            Properties pro = new Properties();//获取配置文件的对象
            FileReader in = new FileReader("pro.txt");//获取输入流
            pro.load(in);//将流加载到配置文件对象中
            in.close();
            return pro.getProperty(key);//返回根据key获取的value值
        }
    }
      控制台输出:is show()
      

    需求:

      当我们升级这个系统时,不要Student类而需要新写一个Student2的类时,这时只需要更改pro.txt的文件内容就可以了。代码就一点不用改动

      新写一个student2的类:

    public class Student2 {
        public void show2(){
            System.out.println("is show2()");
        }
    }

      配置文件更改为:

    className = cn.fanshe.Student2
    methodName = show2

      控制台输出:is show2()

  • 相关阅读:
    跃迁方法论 Continuous practice
    EPI online zoom session 面试算法基础知识直播分享
    台州 OJ 2648 小希的迷宫
    洛谷 P1074 靶形数独
    洛谷 P1433 DP 状态压缩
    台州 OJ FatMouse and Cheese 深搜 记忆化搜索
    台州 OJ 2676 Tree of Tree 树状 DP
    台州 OJ 2537 Charlie's Change 多重背包 二进制优化 路径记录
    台州 OJ 2378 Tug of War
    台州 OJ 2850 Key Task BFS
  • 原文地址:https://www.cnblogs.com/JonaLin/p/12712670.html
Copyright © 2011-2022 走看看