java的反射和内省机制基础探密

来源:互联网 发布:打印软件免费版 编辑:程序博客网 时间:2024/05/18 01:15

Java反射机制和内省机制

A.反射机制

反射在项目里的应用Java的反射机制主要运用在一些框架里,可以通过反射机制动态的获得对象和调用方法,在项目里 action里运用了反射机制来执行特定的方法。如果不运用反射机制,那么在该项目里,一个动作类就必须定义一个action,(这是因为当HTTPServletRequest请求到来时,会自动执行动作类里的execute方法)那必然会使action动作类,非常的繁杂,但其实很多动作是一个模块里的操作,完全可以放到一个动作类里,然后通过反射机制动态获得动作类里的指定方法。这样做的好处非常明显,大大简化了项目代码结构,让整个项目更具模块性。

 

当然,在很多开源框架上,Java反射机制也运用的很广,在框架上的具体运用还不是很清楚,有待以后研究。

 

在这篇文章里,我将介绍一些反射的基本语法和操作:并结合公司的具体运用来进行介绍。

 

Java反射机制可以实现以下功能:

1.       在运行的时候获得任意对象的类:这个可能比较难以理解,但只需先记住这点,然后慢慢看代码和解说,多看几次就会有说领悟。

2.       根据需要,在运行时可构造任意一个类的对象。说道这里我觉得可以说有三个东西帮程序构造对象;第一个是大家最喜欢也是最熟悉的通过类本身创建一个对象。第二个是通过反射得到这个对象的Class(我觉得也可以这样说,获得这个对象对应的Class类的一个对象),然后通过Class调用newInstance()来构造这个对象所代表的类的一个新对象,必须注意的是,ClassnewInstance()方法是不带参数的。如果要构造带指定参数的对象,则要用第三种方法。第三种方法也必须先获得这个对象对应Class类的一个对象,然后通过这个Class的对象调用getConstructor(Class[]  cl)得到一个Constructor的对象,最后Constructor的对象再调用newInstance(Object[] objs)方法来构造带参数的对象。

3.       在运行时获得任意对象的方法,包括私有的方法和受保护的方法,但感觉即使能获得也没啥用处?如果有高人知道具体作用请告知。

4.       可在运行时获得任意对象的属性。包括私有属性

 

在上述介绍中提到一个Class类,该类和绝大多数类一样继承了Object类,但它同时也是一个非常个数的类。这个类的实体主要表示的是一个正在运行的对象的classinterface,这个比较好理解,但它还表示enumarrayprimitiveJava Types等。Class类是在ClassLoaderdefineClass()被调用时创建一个Class对象。它是一切反射机制的基础,可以这样说:没有Class就没有反射机制,java功能也就大打折扣。

 

通过类名构造对象:

如果是非基本类型,可通过如下几种方式获得Class类的对象

a.       对象.getClass()

b.       类名.Class

c.       Class.forName(String className):注意这里传一个类名做参数

 基本类型(包括封装类型):

a.       Integer.Class

b.       Integer.TYPE

代码如下:

  无参:

   Class cl=Class.forName(“类名”);

   Object obj=cl.newInstance();

  有参:

public Object getObject(String className, Object[] objs) throws Exception {

    Class class=Class.forName(className);

  Class[] classes=new Class[objs.length];

  for(int i=0;i<objs.length;i++) {

      classes[i]=objs[i].getClass();

    }

  Constructor con=class.getConstructor(classes);

  Object obj=con.newInstance(objs);

    return obj;

}

获取(或执行)某对象的方法:

  public void invoke(Object obj, String methodName, Object[] objs) throws Exception {

         Class class=obj.getClass();

         Class[] classes=new Class[objs.length];

         for(int i=0;i<objs.length;i++) {

                   classes[i]=objs[i].getClass();

         }

         Method method=class.getMethod(methodName, classes);

         method.invoke(obj,objs);

         //注意如果是要执行静态方法,则上面一行不需传obj 直接method.invoke(null,objs);

}

获取某对象的属性:

  public Object getField(Object obj, String fieldName) throws Exception {

         Class class=obj.getClass();

         Field field=class.getField(fieldname);//或得到所有的共有属性getFields();

         Object obj=field.get(obj);//获得指定对象该字段的值,以对象类型返回

         return obj;

         //如果是静态属性则只需field.get(class);

}

 

以上方法都不能获得超类的方法和属性,但可通过该Class对象获得超类的Class对象,通过获得的超类Class对象再获得方法和属性。可通过如下递归来完成:

public void getField(Class class){

        Class cls=class.getSuperclass();

        if(!cls.equals(Object.class)){ 

            Field[] fields = cls.getFields(); 

            getField(cls); 

         } 

     }

B.内省机制:

  本人对内省机制其实只大概知道怎么用,但它具体有什么牛的地方我还没体会到,可能是我做的项目太少的缘故吧;说句废话:实践是检验真理的唯一标准。

 

以下是本人摘自网上资料后整理的,希望对各位观众能有所帮助:

 

内省是JavaBean类的属性和事件的一种处理机制,也就是给定一个JavaBean对象就可以调用它们所有的get/set方法。

 

Java提供一个API来访问属性的get/set方法,通过Introspector来的getBeanInfo(Class<?> startClass, Class<?> endClass)来获得一个对象的BeanInfo信息(它是一个接口),注意其中的2个参数的意义:第一个参数表示需要内省的bean对象所代表的Class的对象;第二个参数表示结束内省的类的Class的对象,一般来说,第二个参数是其直接父类的Class的对象。然后通过这个BeanInfogetPropertyDescriptors()获取每个属性的属性描述器(PropertyDescriptor)的一个数组,该属性描述器表示属性的名字,属性的类型和所有的读写方法。最后通过该属性描述器就可以获得属性的get/set方法对其进行操作。

 

下面我将展示内省机制的基本运用代码:

 

 

public class TestBean{

       private String name;

       private String[] childName;

      

       public String getName() {

           return name;

       }

       public void setName(String name) {

           this.name=name;

       }

       public String[] getChildName() {

           return childName;

       }

       public void setChildName(String[] childName) {

           this.childName=childName;

       }

}

 

 

 

 

 

 

public class TestIntrospector {

       public static void main(String[] args) {

           TestBean bean=new TestBean();

           BeanInfo info=null;

           try {

              info = Introspector.getBeanInfo(bean.getClass());

           } catch (IntrospectionException e) {

              e.printStackTrace();

           }

           PropertyDescriptor[] des=info.getPropertyDescriptors();

           for(PropertyDescriptor pro:des) {

               String str=pro.getName();//获取属性名

               Class type=pro.getPropertyType();//得到属性的类型

               if(type.isArray()) {  //判断是否是数组

                  if(str.equals("childName")) {

              //getComponentType()获得数组类型的类型,如果不是数组,返回null

                    if(type.getComponentType().equals(String.class)) {

                       Method method=pro.getWriteMethod();

                       method.invoke(bean,

new Object[]{new String[]{"bao","ning"}});

 

                    }

                 }

               } else if("name".equals(pro.getName())){

                   Method method=pro.getWriteMethod();

                  method.invoke(bean,new Object[]{"liu"});

               }

          }

       }

}

 

以上代码是内省机制最基本的运用,集体框架上的运用还不的而知,希望广大广众不吝赐教。

原创粉丝点击