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()

  • 相关阅读:
    Java入门
    Java入门
    字符串常用方法(转载--https://www.cnblogs.com/ABook/p/5527341.html)
    SSM-8FastDfs搭建
    SSM7-nginx的反向代理和负载均衡
    SSM-6nginx Linux下的安装
    SSM-5zookeeper在LINUX上自启
    SSM4-Linux上jdk、tomcat、zookeeper------tar zxvf的安装
    SSM3-SVN的安装和搭建环境
    SSM2-搭建maven常见的错误以及解决方法
  • 原文地址:https://www.cnblogs.com/JonaLin/p/12712670.html
Copyright © 2011-2022 走看看