java反射机制

反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。这个能特定我们不常看到,但是在其他的比如C或者C++语言中很不就存在这个特性。一个常见的例子是在JavaBean中,一些组件可以通过一个构造器来操作。这个构造器就是用的反射在动态加载的时候来获取的java中类的属性的。

Java语言允许通过程序化的方式间接对Class进行操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数、属性和方法等。Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能,这就为使用程序化方式操作Class对象开辟了途径。


Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;生成动态代理。

简单实例

package com.baobaotao.reflect; 
public class Car { 
    private String brand; 
    private String color; 
    private int maxSpeed; 

     //①默认构造函数 
    public Car(){} 

     //②带参构造函数 
    public Car(String brand,String color,int maxSpeed){  
        this.brand = brand; 
        this.color = color; 
        this.maxSpeed = maxSpeed; 
    } 

     //③未带参的方法 
    public void introduce() {  
       System.out.println("brand:"+brand+";color:"+color+";maxSpeed:" +maxSpeed); 
    } 
     //省略参数的getter/Setter方法 
     … 
}

一般情况下,我们会使用如下的代码创建Car的实例:

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

以上两种方法都采用传统方式的直接调用目标类的方法,下面我们通过Java反射机制以一种更加通用的方式间接地操作目标类:

package com.baobaotao. reflect; 
import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
public class ReflectTest { 
    public static Car  initByDefaultConst() throws Throwable 
    { 
        //①通过类装载器获取Car类对象 
        ClassLoader loader = Thread.currentThread().getContextClassLoader();  
        Class clazz = loader.loadClass("com.baobaotao.reflect.Car");  

          //②获取类的默认构造器对象并通过它实例化Car 
        Constructor cons = clazz.getDeclaredConstructor((Class[])null);  
        Car car = (Car)cons.newInstance(); 


          //③通过反射方法设置属性 
        Method setBrand = clazz.getMethod("setBrand",String.class);         
        setBrand.invoke(car,"红旗CA72");       
        Method setColor = clazz.getMethod("setColor",String.class); 
        setColor.invoke(car,"黑色");       
        Method setMaxSpeed = clazz.getMethod("setMaxSpeed",int.class); 
        setMaxSpeed.invoke(car,200);         
        return car; 
    } 

    public static void main(String[] args) throws Throwable { 
        Car car = initByDefaultConst(); 
        car.introduce(); 
    } 
}

输出结果:
brand:红旗CA72;color:黑色;maxSpeed:200

这说明我们完全可以通过编程方式调用Class的各项功能,这和直接通过构造函数和方法调用类功能的效果是一致的,只不过前者是间接调用,后者是直接调用罢了。

在ReflectTest中,使用了几个重要的反射类,分别是ClassLoader、Class、Constructor和Method,通过这些反射类就可以间接调用目标Class的各项功能了。在①处,我们获取当前线程的ClassLoader,然后通过指定的全限定类“com.baobaotao.beans.Car”装载Car类对应的反射实例。在②处,我们通过Car的反射类对象获取Car的构造函数对象cons,通过构造函数对象的newInstrance()方法实例化Car对象,其效果等同于new Car()。在③处,我们又通过Car的反射类对象的getMethod(String methodName,Class paramClass)获取属性的Setter方法对象,第一个参数是目标Class的方法名;第二个参数是方法入参的对象类型。获取方法反射对象后,即可通过invoke(Object obj,Object param)方法调用目标类的方法,该方法的第一个参数是操作的目标类对象实例;第二个参数是目标方法的入参。

粗体所示部分的信息即是通过反射方法操控目标类的元信息,如果我们将这些信息以一个配置文件的方式提供,就可以使用Java语言的反射功能编写一段通用的代码对类似于Car的类进行实例化及功能调用操作了。

IOC(Inverse of
Control)可翻译为“控制反转”,但大多数人都习惯将它称为“依赖注入”。在Spring中,通过IOC可以将实现类、参数信息等配置在其对应的配置文件中,那么当需要更改实现类或参数信息时,只需要修改配置文件即可,这种方法在上例的基础上更进一步的降低了类与类之间的耦合。我们还可以对某对象所需要的其它对象进行注入,这种注入都是在配置文件中做的,Spring的IOC的实现原理利用的就是Java的反射机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值