JAVA反射机制深入学习(二)实例演示JAVA反射机制的应用

来源:互联网 发布:蜂窝数据打开自动关闭 编辑:程序博客网 时间:2024/05/22 18:23
编写一个简单示例开始探访Java反射机制的征程,通过比较传统方法以及反射机制创建类实例的不同,来介绍Java反射机制的原理

首先创建一个Bean :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;}}

在传统的调用方法中,我们是使用构造函数设置属性或者使用set方法设置属性
      1. 构造函数方法:
Car car = new Car(“红旗轿车”, “黑色”, “180”);
      2. Set方法:
Car car = new Car(); car.setBrand(“红旗轿车”);
而使用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.使参数的构造器对象实例化CarCar 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的特定功能,这和直接通过构造函数和方法来调用类的功能的效果的内容是一致的。只不过前者是间接调用,而后者是直接调用罢了。
在刚才示例类中我们使用了几个重要的反射类:
ClassLoader:类加载器
Class:类对象
Constructor:类的构造函数
Method:类方法
通过这些反射类就可以间接调用目标class的某些功能。

0 0
原创粉丝点击