Java内省机制简单了解_Introspector

Java内省机制

内省(Introspector) ——内省是Java语言的一种重要特性。使用内省我们可以在运行时得到一个类的内部信息。这些信息包括方法、属性、构造函数及其他。内省的一个应用是开发使用插件的应用程序。应用程序可以在运行时获取并使用插件类的构造函数、方法和属性。内省也可以应用于创建Java Beans和Javadocs中。

JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”。方法比较少。这些信息储存在类的私有变量中,通过set()、get()获得。

在类UserInfo中有属性 userName, 那我们可以通过 getUserName,setUserName来得到其值或者设置新的值。通过 getUserName/setUserName来访问 userName属性,这就是默认的规则。 Java JDK中提供了一套 API 用来访问某个属性的 getter/setter 方法,这就是内省。


JDK内省类库:

PropertyDescriptor类:

PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:

  • getPropertyType(),获得属性的Class对象;

  • getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法;

  • hashCode(),获取对象的哈希值;

  •  setReadMethod(Method readMethod),设置用于读取属性值的方法;

  • setWriteMethod(Method writeMethod),设置用于写入属性值的方法。

Introspector类:

将JavaBean中的属性封装起来进行操作。在程序把一个类当做JavaBean来看,就是调用Introspector.getBeanInfo()方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息。

getPropertyDescriptors(),获得属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。


实例代码:

package introspector;

public class UserInfo {

    private long userId;
    private String userName;
    private int age;
    private String emailAddress;

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

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

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

}


测试代码:

package introspector;

import org.junit.Test;

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

/**
 * Created with IntelliJ IDEA.
 * User: ASUS
 * Date: 14-7-10
 * Time: 下午4:41
 * To change this template use File | Settings | File Templates.
 */
public class IntrospectorTest {

    @Test
    public void test0877() throws IntrospectionException, InvocationTargetException, IllegalAccessException {

        String userNameDesc = "userName";
        UserInfo userInfo = new UserInfo();

        /**
         * @param propertyName The programmatic name of the property.
         * @param beanClass The Class object for the target bean.  For
         *          example sun.beans.OurButton.class.
         */
        PropertyDescriptor propDesc = new PropertyDescriptor(userNameDesc, UserInfo.class);
        Method methodSetUserName = propDesc.getWriteMethod();

        methodSetUserName.invoke(userInfo, "lyx");
        System.out.println("set userName:" + userInfo.getUserName());
    }

    @Test
    public void test98776776() throws IntrospectionException, InvocationTargetException, IllegalAccessException {

        String userNameDesc = "userName";
        UserInfo userInfo = new UserInfo();


        PropertyDescriptor proDescriptor = new PropertyDescriptor(userNameDesc, UserInfo.class);
        Method methodGetUserName = proDescriptor.getReadMethod();

        userInfo.setUserName("sdsdsdsd");
        Object objUserName = methodGetUserName.invoke(userInfo);
        System.out.println("get userName:" + objUserName.toString());
    }

    @Test
    public void test755() throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        String userNameDesc = "userName";
        UserInfo userInfo = new UserInfo();

        BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);

        PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();
        if (proDescrtptors != null && proDescrtptors.length > 0) {
            for (PropertyDescriptor propDesc : proDescrtptors) {
                if (propDesc.getName().equals(userNameDesc)) {
                    Method methodSetUserName = propDesc.getWriteMethod();
                    methodSetUserName.invoke(userInfo, "alan");
                    System.out.println("set userName:" + userInfo.getUserName());
                    break;
                }
            }
        }
    }


    @Test
    public void test98765() throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        String userNameDesc = "userName";
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName("init");

        BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);
        PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();
        if (proDescrtptors != null && proDescrtptors.length > 0) {
            for (PropertyDescriptor propDesc : proDescrtptors) {
                if (propDesc.getName().equals(userNameDesc)) {
                    Method methodGetUserName = propDesc.getReadMethod();
                    Object objUserName = methodGetUserName.invoke(userInfo);
                    System.out.println("get userName:" + objUserName.toString());
                    break;
                }
            }
        }
    }
}

详细请参见:http://www.cnblogs.com/peida/archive/2013/06/03/3090842.html


附:把JavaBean对象转为Map对象

public static <T> Map<String, Object> beanToMap(T bean) {
    Class<? extends Object> type = bean.getClass();
    Map<String, Object> returnMap = new HashMap<String, Object>();
    try {
        BeanInfo beanInfo = Introspector.getBeanInfo(type);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            String propertyName = descriptor.getName();
            if (!propertyName.equals("userRoles") && !propertyName.equals("user")) {
                if (!propertyName.equals("class")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(bean);
                    returnMap.put(propertyName, result != null ? result : "");
                }
            }
        }
    } catch (IntrospectionException e) {
        throw new RuntimeException("分析类属性失败", e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException("分析类属性失败", e);
    } catch (InvocationTargetException e) {
        throw new RuntimeException("分析类属性失败", e);
    }
    return returnMap;
}

@Test
public void test9764567() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUserName("lyx");
    userInfo.setAge(12);
    userInfo.setEmailAddress("sdsdsd");
    userInfo.setUserId(231323L);
    Map bean = beanToMap(userInfo);

    Set<Map.Entry<String, Object>> entrySet = bean.entrySet();
    for (Map.Entry<String, Object> entry : entrySet) {
        System.out.println(entry.getKey());
        System.out.println(entry.getValue());
    }
}


====END====


你可能感兴趣的:(Java内省机制简单了解_Introspector)