关于反射的一点理解

最近在看《Spring 3.x企业应用开发实战》这本书,这本书上面写了对于反射的一些理解。虽然之前也看过很多次反射的内容,但是一直感觉自己对反射半懂不懂的。看了这本书上写的,有一种茅塞顿开的感觉,所以在这里记录一下。

首先我们写一个Car类,它拥有两个构造函数、两个方法和三个属性。

 1 package com.baobaotao.reflect;
 2 
 3 /**
 4  * Created by Jean on 16/4/25.
 5  */
 6 public class Car {
 7     private String brand;
 8     private String color;
 9     private int maxSpeed;
10 
11     public Car(){}
12 
13     public Car(String brand, String color, int maxSpeed) {
14         this.brand = brand;
15         this.color = color;
16         this.maxSpeed = maxSpeed;
17     }
18 
19     public void introduce() {
20         System.out.println("brand:" + brand + ";color:" + color
21         + ";maxSpeed:" + maxSpeed);
22     }
23 
24     public String getBrand() {
25         return brand;
26     }
27 
28     public void setBrand(String brand) {
29         this.brand = brand;
30     }
31 
32     public String getColor() {
33         return color;
34     }
35 
36     public void setColor(String color) {
37         this.color = color;
38     }
39 
40     public int getMaxSpeed() {
41         return maxSpeed;
42     }
43 
44     public void setMaxSpeed(int maxSpeed) {
45         this.maxSpeed = maxSpeed;
46     }
47 }

一般而言,我们创建Car的实例和调用方法的时候,是如下的过程:

Car car = new Car();
car.setBrand("红旗CA72",“黑色”,200);

这就是我们传统的直接创造实例和调用方法的过程。

直接创造实例的过程如下:

1.Car car是声明一个引用变量,要求虚拟机分配空间给名字为car的引用变量,就像一个控制Car的遥控器。

2.new Car()是要求Java虚拟机分配堆空间给新建立的Car对象

3.中间的“=”号表示着将这个堆里的Car对象,交给引用类型car来控制。

4.car.setBrand方法,表示通过引用对象car来Car对象来执行setBrand方法。

 

接下来我们使用反射的方式来调用:

 1 package com.baobaotao.reflect;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  * Created by Jean on 16/4/25.
 8  */
 9 public class ReflectTest {
10     public static Car initByDefaultConst() throws Throwable {
11         //通过类装载器获取Car类对象
12         ClassLoader loader = Thread.currentThread().getContextClassLoader();
13         Class clazz = loader.loadClass("com.baobaotao.reflect.Car");
14         //获取类的默认构造器对象并通过它实例化Car
15         Constructor cons = clazz.getDeclaredConstructor((Class[])null);
16         Car car = (Car)cons.newInstance();
17         //通过反射的方法设置属性
18         Method setBrand = clazz.getMethod("setBrand", String.class);
19         setBrand.invoke(car, "红旗CA72");
20         Method setColor = clazz.getMethod("setColor", String.class);
21         setColor.invoke(car, "黑色");
22         Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
23         setMaxSpeed.invoke(car, 200);
24         return car;
25     }
26 
27     public static void main(String[] args) throws Throwable {
28         Car car = initByDefaultConst();
29         car.introduce();
30     }
31 }

运行以上程序,在控制台上将打印出以下信息:

brand:红旗CA72;color:黑色;maxSpeed:200
 
接下来具体说说反射的方法:
Java的执行过程,我们简单理解为几步:
1,Java文件由编译器编译成class文件;
2,class文件由JVM
装载(查找和导入Class文件)
链接(执行校验、准备和解析步骤)
和初始化(对类的静态变量、静态代码块执行初始化工作)
 
传统的方法,用的是我们所谓的静态编译,指的是静态编译就是在编译的时候把你所有的内容都编译进class里去,然后最后一起执行。
而反射,用的是动态的编译,在编译的时候不急着编译进去,等到了最后JVM装载的过程中,再通过一些对class的操作来执行一些操作。
 
因为Class本身也是一个特殊的类,反射就是利用了这个特点,直接对class本身进行操作:
1.首先通过ClassLoader获取Car对象的Class
2.然后获取类的默认构造器对象并通过它实例化Car
3.再通过反射来设置属性
 
 
 
 
posted on 2016-04-25 17:14  景大爷  阅读(337)  评论(0编辑  收藏  举报