美文网首页
JAVA反射机制

JAVA反射机制

作者: 刘荣杰 | 来源:发表于2021-05-17 12:13 被阅读0次

    JAVA反射概念

      JAVA反射(Reflection):在运行状态中,对于任意一类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    先决概念

      在学习JAVA的反射机制前我们得先了解下JAVA中的几大对象 Class、Constructor、Field、Method.。
      在JAVA程序运行时我们写的的Book.java文件,里面是Book对象有对应的属性和方法,我们通过编辑器IDEA编译运行,首先将Book.java转化为Book.class字节码文件,然后将字节码文件加载进jVM中,字节码文件会在JVM的方法区生成该类的类对象即Class对象,然后我们需要用到的时候根据该Class对象生成实例,生成的实例放在堆中,实例引用放在栈中。(以后有机会补JVM虚拟机内存分布以及类加载全过程)
     emsp;获取Class对象有三种方法。我们拿Book举例

    @Data
    public class Book {
        private int id;
        private String name;
        private String type;
    }
    

    获取Book的Class对象

            Class book1=null;
            Class book2=null;
            Class book3=null;
            //获取Class对象的第一种方法
            try {
                book1=Class.forName("cn.lovepi.reflection.bean.Book");
                System.out.println("book1==>"+book1);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            //第二种方法
            Book book=new Book();
            Object object=book;
            book2=object.getClass();
            System.out.println("book2==>"+book2);
            //第三种方法
            book3=Book.class;
            System.out.println("book3==>"+book3);
    
    

    Class对象常用方法:
    getName() 获得类中完整名称
    getDeclaredFields() 获得类中的所有属性
    getDeclaredMethods() 获得类中所有的方法
    getConstructors() 获得类构造方法
    newInstance() 实例化类对象
    就是通过Class对象可以得到该类的所有信息包括属性,方法,构造器。

    实际应用

    我们先定义一个Car类

    public class Car {
        private String brand;
     
        private String color;
     
        private int maxSpeed;
     
        //1.默认构造函数
        public Car(){
            System.out.println("init car!!");
            }
        
        //2.带参构造函数
        public Car(String brand,String color,int maxSpeed){
            this.brand = brand;
            this.color = color;
            this.maxSpeed = maxSpeed;
        }
        
        //3.未带参的方法
        public void introduce() {
           System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);
        }
     
        public String getBrand() {
            return brand;
        }
     
        public void setBrand(String brand) {
            this.brand = brand;
        }
     
        public String getColor() {
            return color;
        }
     
        public void setColor(String color) {
            this.color = color;
        }
     
        public int getMaxSpeed() {
            return maxSpeed;
        }
     
        public void setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
        }
    }
    

    Java反射机制

    public class ReflectTest {
     
     
        /**
         * 通过默认的构造方法来实例化car,并获取car的相关属性。
         * @return
         * @throws Throwable
         */
        public static Car  initByDefaultConst() throws Throwable
        {
            //1.通过类装载器获取Car类对象
            //使用当前线程获取类加载器
            ClassLoader loader = Thread.currentThread().getContextClassLoader();        
            //通过使用全限定类名来装载Car类对应的反射实例
            Class clazz = loader.loadClass("cn.lovepi.chapter02.reflect.Car");
        
            //2.获取类的默认构造器对象并实例化Car
            //通过Car的反射类对象来获取Car的构造函数对象.
            Constructor cons = clazz.getDeclaredConstructor((Class[])null);
            //通过构造函数对象的newInstance方法来实例化Car对象,其效果等同与new Car()
            Car car = (Car)cons.newInstance();
            
            //3.通过反射方法设置属性
            //通过Car的反射类对象的getMethod方法来获取相应的set方法对象.
            //第一个参数是目标class的方法,第二个参数是方法注册的对象类型
            Method setBrand = clazz.getMethod("setBrand",String.class);     
            //通过invoke方法来调用目标类的方法
            //该方法的第一个参数是操作的目标类示例,第二个参数则是目标方法的主参
            setBrand.invoke(car,"奔驰");
            Method setColor = clazz.getMethod("setColor",String.class);
            setColor.invoke(car,"黑色");      
            Method setMaxSpeed = clazz.getMethod("setMaxSpeed",int.class);
            setMaxSpeed.invoke(car,200);        
            return car;
        }
     
        /**
         * 获取类的带有参数的构造器对象来实例化car并设置相关的属性
         * @return
         * @throws Throwable
         */
        public static Car initByParamConst()  throws Throwable{
            //1.通过类装载器获取Car类对象
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            Class clazz = loader.loadClass("cn.lovepi.chapter02.reflect.Car");
            
            //2.获取类的带有参数的构造器对象
            Constructor cons = clazz.getDeclaredConstructor(new Class[]{String.class,String.class,int.class});
            
            //3.使参数的构造器对象实例化Car
            Car car = (Car)cons.newInstance(new Object[]{"宝马","红色",180});
            return car; 
        }
        
        public static void main(String[] args) throws Throwable {
            Car car1 = initByDefaultConst();
            Car car2 = initByParamConst();
            car1.introduce();
            car2.introduce();
        }
    }
    

    总结所谓反射机制就是我们知道了这个Class就能干关于这个Class的一切事情。

    相关文章

      网友评论

          本文标题:JAVA反射机制

          本文链接:https://www.haomeiwen.com/subject/clqjjltx.html