Introspector与反射

    xiaoxiao2021-04-19  88

    原文地址:Introspector与反射 作者:jackeychow

    一》:Introspector类介绍

     

    Introspector与反射类似,主要是对Java Bean属性、方法等的一种处理方法.

     

    1. Class Diagram

     

     

     

    2. 实例

     

    package com.siyuan.jdktest;

    import java.beans.BeanDescriptor; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.MethodDescriptor; import java.beans.PropertyDescriptor; import java.lang.reflect.Method;

    class Person {    private String name;    private int age;

       public int getAge() {   return age;  }

       public void setAge(int age) {   this.age = age;  }

       public String getName() {   return name;  }

       public void setName(String name) {   this.name = name;  }   }

    public class IntrospectorTest {

       public static void main(String[] args) throws IntrospectionException {   // TODO Auto-generated method stub   BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);      System.out.println("BeanDescriptor===========================================");   BeanDescriptor beanDesc = beanInfo.getBeanDescriptor();   Class cls = beanDesc.getBeanClass();   System.out.println(cls.getName());      System.out.println("MethodDescriptor===========================================");   MethodDescriptor[] methodDescs = beanInfo.getMethodDescriptors();   for (int i = 0; i < methodDescs.length; i++) {    Method method = methodDescs[i].getMethod();    System.out.println(method.getName());   }      System.out.println("PropertyDescriptor===========================================");   PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors();   for (int i = 0; i < propDescs.length; i++) {    Method methodR = propDescs[i].getReadMethod();    if (methodR != null) {     System.out.println(methodR.getName());    }    Method methodW = propDescs[i].getWriteMethod();    if (methodW != null) {     System.out.println(methodW.getName());    }   }  }

    }

    3. 运行结果

     

    BeanDescriptor=========================================== com.siyuan.jdktest.Person MethodDescriptor=========================================== hashCode setAge equals wait wait notify getClass toString getAge notifyAll setName wait getName PropertyDescriptor=========================================== getAge setAge getClass getName setName

     

     

    二》:JAVA反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。 1. 得到某个对象的属性

    Java代码 public Object getProperty(Object owner, String fieldName) throws Exception {         Class ownerClass = owner.getClass();             Field field = ownerClass.getField(fieldName);             Object property = field.get(owner);             return property;    }   public Object getProperty(Object owner, String fieldName) throws Exception ( Class ownerClass = owner.getClass(); Field field = ownerClass.getField(fieldName); Object property = field.get(owner); return property; }

      Class ownerClass = owner.getClass():得到该对象的Class。 Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。 Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。 2. 得到某个类的静态属性

    Java代码 public Object getStaticProperty(String className, String fieldName)                 throws Exception {         Class ownerClass = Class.forName(className);             Field field = ownerClass.getField(fieldName);             Object property = field.get(ownerClass);             return property;    }   public Object getStaticProperty(String className, String fieldName) throws Exception { Class ownerClass = Class.forName(className); Field field = ownerClass.getField(fieldName); Object property = field.get(ownerClass); return property; }

      Class ownerClass = Class.forName(className) :首先得到这个类的Class。 Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。 Object property = field.get(ownerClass) :这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。 3. 执行某对象的方法

    Java代码 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {             Class ownerClass = owner.getClass();             Class[] argsClass = new Class[args.length];             for (int i = 0, j = args.length; i < j; i++) {             argsClass[i] = args[i].getClass();         }             Method method = ownerClass.getMethod(methodName,argsClass);             return method.invoke(owner, args);    }   public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception { Class ownerClass = owner.getClass(); Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass(); } Method method = ownerClass.getMethod(methodName,argsClass); return method.invoke(owner, args); }

      Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。 5~9行:配置参数的Class数组,作为寻找Method的条件。 Method method = ownerClass.getMethod(methodName, argsClass):通过methodName和参数的argsClass(方法中的参数类型集合)数组得到要执行的Method。 method.invoke(owner, args):执行该Method.invoke方法的参数是执行这个方法的对象owner,和参数数组args,可以这么理解:owner对象中带有参数args的method方法。返回值是Object,也既是该方法的返回值。 4. 执行某个类的静态方法

    Java代码 public Object invokeStaticMethod(String className, String methodName,                 Object[] args) throws Exception {         Class ownerClass = Class.forName(className);             Class[] argsClass = new Class[args.length];             for (int i = 0, j = args.length; i < j; i++) {             argsClass[i] = args[i].getClass();         }            Method method = ownerClass.getMethod(methodName,argsClass);             return method.invoke(null, args);     }   public Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception { Class ownerClass = Class.forName(className); Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass(); } Method method = ownerClass.getMethod(methodName,argsClass); return method.invoke(null, args); }

      基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。 5. 新建实例

    Java代码 public Object newInstance(String className, Object[] args) throws Exception {         Class newoneClass = Class.forName(className);             Class[] argsClass = new Class[args.length];             for (int i = 0, j = args.length; i < j; i++) {             argsClass[i] = args[i].getClass();         }             Constructor cons = newoneClass.getConstructor(argsClass);             return cons.newInstance(args);        }   public Object newInstance(String className, Object[] args) throws Exception { Class newoneClass = Class.forName(className); Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass(); } Constructor cons = newoneClass.getConstructor(argsClass); return cons.newInstance(args); }

      这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。 Class newoneClass = Class.forName(className):第一步,得到要构造的实例的Class。 第5~第9行:得到参数的Class数组。 Constructor cons = newoneClass.getConstructor(argsClass):得到构造子。 cons.newInstance(args):新建实例。 6. 判断是否为某个类的实例

    Java代码 public boolean isInstance(Object obj, Class cls) {         return cls.isInstance(obj);    }   public boolean isInstance(Object obj, Class cls) { return cls.isInstance(obj); }

      7. 得到数组中的某个元素

    Java代码 public Object getByArray(Object array, int index) {         return Array.get(array,index);    }   public Object getByArray(Object array, int index) { return Array.get(array,index); }
    转载请注明原文地址: https://ju.6miu.com/read-676023.html

    最新回复(0)