内省(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;
}

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

  1. Java 内省(Introspector)深入理解

    Java 内省(Introspector)深入理解 一些概念: 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类 ...

  2. Java 内省(Introspector)和 BeanUtils

    人生若只如初见,何事秋风悲画扇. 概述 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息, ...

  3. JAVA内省(Introspector)

    什么是Java内省:内省是Java语言对Bean类属性.事件的一种缺省处理方法. Java内省的作用:一般在开发框架时,当需要操作一个JavaBean时,如果一直用反射来操作,显得很麻烦:所以sun公 ...

  4. 聊聊Java内省Introspector

    前提 这篇文章主要分析一下Introspector(内省,应该读xing第三声,没有找到很好的翻译,下文暂且这样称呼)的用法.Introspector是一个专门处理JavaBean的工具类,用来获取J ...

  5. Java 内省 Introspector

    操纵类的属性,有两种方法 反射 内省 面向对象的编程中,对于用户提交过来的数据,要封装成一个javaBean,也就是对象 其中Bean的属性不是由字段来决定的,而是由get和Set方法来决定的 pub ...

  6. java内省Introspector

    大纲: JavaBean 规范 内省 一.JavaBean 规范 JavaBean —般需遵循以下规范. 实现 java.io.Serializable 接口. javaBean属性是具有getter ...

  7. 【小家Spring】Spring IoC是如何使用BeanWrapper和Java内省结合起来给Bean属性赋值的

    #### 每篇一句 > 具备了技术深度,遇到问题可以快速定位并从根本上解决.有了技术深度之后,学习其它技术可以更快,再深入其它技术也就不会害怕 #### 相关阅读 [[小家Spring]聊聊Sp ...

  8. 【小家Spring】聊聊Spring中的数据绑定 --- BeanWrapper以及内省Introspector和PropertyDescriptor

    #### 每篇一句 > 千古以来要饭的没有要早饭的,知道为什么吗? #### 相关阅读 [[小家Spring]聊聊Spring中的数据转换:Converter.ConversionService ...

  9. 深入理解Java:内省(Introspector)

    深入理解Java:内省(Introspector) 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传 ...

随机推荐

  1. jQ效果:jQuery时间轴插件jQuery Timelinr

    前言 这是一款可用于展示历史和计划的时间轴插件,尤其比较适合一些网站展示发展历程.大事件等场景.该插件基于jQuery,可以滑动切换.水平和垂直滚动.支持键盘方向键.经过扩展后可以支持鼠标滚轮事件. ...

  2. 【读书笔记】iOS-强类型与弱类型

    id类型是一个通用类型,OC使用id表示任意类型的对象,它可以作为一个占位符表示这是一个不确定的类型的对象或者引用.因此,所有的对象都 可以用id来表示.这很有用,想象一下,如果你需要实现一个通用的链 ...

  3. python之while循环/格式化输出/运算符/初始编码/成员变量

    一.主要内容:1.while 循环 (难点)while 条件: 循环体 break: 直接跳出循环continue:停止当前本次循环,继续执行下一次循环.不会中断循环能让循环退出:(1)break ( ...

  4. openvswitch技术总结

    OVS技术总结 一.OVS的组成 二.OVS的匹配条件和动作 三.OVS的发展方向 四.OVS的操作实践 OVS与Namespace配合模拟租户之间的数据通信 基本思路: Namespace模拟出不同 ...

  5. openldap系列

    openldap系列 阅读视图 系列介绍 openldap系列目录 1. 系列介绍 本系列文档大部分来自于郭大勇老师的<OpenLDAP实战指南>,少部分来自于互联网.所有文档均已经过本人 ...

  6. asp.net webapi 自定义身份验证

    /// <summary> /// 验证 /// </summary> /// Account API账号 /// TimeStamp 请求时间 /// Sign 所有请求参数 ...

  7. LVS (Linux Virtual Server) - 负载均衡集群 - keepalived

    今天稍微了解了LVS 的原理和使用,在网络上找到不少好文章,稍微加以处理并在这里备份: 原理介绍:Linux Virtual Server 关于:http://www.linuxvirtualserv ...

  8. 峰值QPS/QPS/PV/UV/服务器数量/并发数/吐吞量/响应时间计算公式

    QPS:每秒查询率(Query Per Second) ,每秒的响应请求数,也即是最大吞吐能力.QPS = req/sec = 请求数/秒QPS统计方式 [一般使用 http_load 进行统计]QP ...

  9. Django框架的简介

    Django框架的背景 Django是一款基于Python开发的全栈式一体化Web 应用框架.2003 年问世之初,它只是 美国一家报社的内部工具,2005 年 7 月使用 BSD 许可证完成了开源. ...

  10. 教程+资源,python scrapy实战爬取知乎最性感妹子的爆照合集(12G)!

    一.出发点: 之前在知乎看到一位大牛(二胖)写的一篇文章:python爬取知乎最受欢迎的妹子(大概题目是这个,具体记不清了),但是这位二胖哥没有给出源码,而我也没用过python,正好顺便学一学,所以 ...