Java:内省(Introspector)

  内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。

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

例如UserInfo

public class UserInfo {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    publicint getAge() {
        return age;
    }

    publicvoid setAge(int age) {
        this.age = age;
    }
}

  在UserInfo中有属性name,我们可以通过getName,setName来访问其值或者设置其值.通过getName/setName来访问其属性name,这就是默认规则,java jdk中提供一套api用来访问某个属性的getter(),setter()方法即为内省。

JDK内省类库:

PropertyDescriptor类:

  表示JavaBean类通过存储器导出一个属性。

  主要方法:

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

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

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

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

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

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class BeanInfoUtil {

    public static void main(String[] args) {
        UserInfo user = new UserInfo();
        try {
            setProperty(user, "name");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(user.getName());
        System.out.println(getProperty(UserInfo.class, "name"));
    }

    public static void setProperty(Object bean, String propertyName) throws Exception {
        PropertyDescriptor pd = new PropertyDescriptor(propertyName, bean.getClass());
        Method methodSetProperty = pd.getWriteMethod();
        methodSetProperty.invoke(bean, "123");
    }

    public static String getProperty(Class<?> bean, String propertyName) {
        try {
            //通过反射实例化对象
            Object be = bean.newInstance();
            //创建PropertyDescriptor对象
            PropertyDescriptor pd = new PropertyDescriptor(propertyName, be.getClass());
            //调用getWriteMethod方法来为对象属性设置值
            pd.getWriteMethod().invoke(be, "123");
            //调用getReadMethod方法来获取对象的属性值
            return (String) pd.getReadMethod().invoke(be, new Object[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

class UserInfo {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

Introspector类:

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

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

public static void setPropertyIntrospector(Class<?> bean, String propertyName) {
  try {
    //第一个参数要分析的bean类,
    //第二个参数是从第一个参数开始到某个父类结束(当bean存在多个父类的时候可以通过该方法来限定)
    BeanInfo beanInfo = Introspector.getBeanInfo(bean, Object.class);
    //获取整个bean的属性描述
    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
    if(pds != null && pds.length > 0) {
      for(PropertyDescriptor pd : pds) {
        if(pd.getName().equals(propertyName)) {
          Object obj = bean.newInstance();
          pd.getWriteMethod().invoke(obj, "张三");
          System.out.println(pd.getReadMethod().invoke(obj, new Object[0]));
        }
      }
    }
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }}

======================使用内省机制完成javaBean和Map之间的相互转换====================

 public static Map<String, Object> beanToMap(Object bean) {
    if(bean == null) return null;

    try {
        Map map = newHashMap();
        BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        if(pds != null && pds.length > 0) {
            for(PropertyDescriptor pd : pds) {
                String key = pd.getName();
                //过滤掉class属性
                if(!key.equals("class")) {
                    Object value = pd.getReadMethod().invoke(bean, new Object[]{});
                    //此处如果明确知道该类中含有某个对象可以这种处理
                    if(value instanceof Person) {
                        //递归调用
                        Map m = beanToMap(value);
                        map.put(key, m);
                    } else {
                        map.put(key, value);
                    }
                }
            }
        }
        return map;
    } catch (Exception e) {
        e.printStackTrace();
    }
        return null;
}

public static Object mapToBean(Class<?> beanClass, Map map) {
    if(map == null) return null;

    try {
        //内部实例化对象
        Object bean = beanClass.newInstance();
        BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        if(pds != null && pds.length > 0) {
            for(PropertyDescriptor pd : pds) {
                String key = pd.getName();
                Object value = map.get(key);
                if(value instanceof Map) {
                    //递归调用,嵌套map的转换,map中存放map,map中的map表示一个对象
                    Object obj = mapToBean(Person.class, (Map)value);
                    pd.getWriteMethod().invoke(bean, obj);
                } else {
                    pd.getWriteMethod().invoke(bean, value);
                }
            }
        }
        return bean;
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}
时间: 2024-10-05 12:38:15

Java:内省(Introspector)的相关文章

Java 内省 Introspector

操纵类的属性,有两种方法 反射 内省 面向对象的编程中,对于用户提交过来的数据,要封装成一个javaBean,也就是对象 其中Bean的属性不是由字段来决定的,而是由get和Set方法来决定的 public class Person { private String name ; private String password; private int age; public String getName() { return name; } public void setName(String

java内省(Introspector)

内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为"值对象"(Value Object),或"VO".方法比较少.这些信息储存在类的私有变量中,通过set().get()获得 Java JDK中提供了一套 API 用来访

Java:内省(Introspector)深入理解

内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为"值对象"(Value Object),或"VO".方法比较少.这些信息储存在类的私有变量中,通过set().get()获得. 例如类UserInfo : package

java内省Introspector

大纲: JavaBean 规范 内省 一.JavaBean 规范 JavaBean —般需遵循以下规范. 实现 java.io.Serializable 接口. javaBean属性是具有getter/setter方法的private成员变量.也可以只提供getter方法,这样的属性叫只读属性:也可以只提供setter方法,这样的属性叫只写属性. JavaBean 必须有一个空的构造函数 JavaBean 必须有一个public构造函数 二.内省 首先内省的本质也是利用反射 通过内省可以快速拿到

深入理解Java:内省(Introspector)

内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为"值对象"(Value Object),或"VO".方法比较少.这些信息储存在类的私有变量中,通过set().get()获得. 例如类UserInfo : package

Java内省

大家都知道,Java给我提供了反射机制,使我们可以获取到每一个类的每一个属性和方法,并对此进行操作.但是利用反射来操作对象时过于麻烦,所以sun公司就基于反射机制给大家提供了一个更加简单实用的api,那就是内省(Introspector),而内省这套api将会使我们操作JavaBean的属性更加方便. 1.什么是Javabean? ①类必须是公共的 ②类必须具备无参构造器 2.什么是Javabean的属性? 要理解内省的概念,我们先来理解一下什么叫Javabean的属性,下面我们猜下该Javab

内省(Introspector)

内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为"值对象"(Value Object),或"VO".方法比较少.这些信息储存在类的私有变量中,通过set().get()获得. 例如类UserInfo : package

内省Introspector(反射操作javaBean)

一:内省是一种特殊的反射,来更方便的操作javaBean对象,通过内省可以获取到类字节码的描述器, 然后解剖每一个字段,获取每个字段的读写方法,即get/set方法的反射,然后获取或者是封装bean的value 下面是通过内省向Bean中set值得示例: public static <T> T toBean(T t){ Class<?> clazz = t.getClass(); try { //根据Class对象获取该类的BeanInfo信息 BeanInfo beanInfo

java内省机制

一.概念 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”.方法比较少.这些信息储存在类的私有变量中,通过set().get()获得.通俗地讲,每一对set/get方法都是对应的javaBean的一