什么是内省?

  Java语言对bean类属性、事件的一种缺省处理方法,例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值

什么是JavaBean?

  JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。

下面这个Person类就是一个JavaBean,大家参考一下:

  1. public class Person {
  2.  
  3. private int id;
  4. private String name;
  5.  
  6. public Person() {
  7. }
  8.  
  9. public Person(int id, String name) {
  10. this.id = id;
  11. this.name = name;
  12. }
  13.  
  14. public int getId() {
  15. return id;
  16. }
  17.  
  18. public void setId(int id) {
  19. this.id = id;
  20. }
  21.  
  22. public String getName() {
  23. return name;
  24. }
  25.  
  26. public void setName(String name) {
  27. this.name = name;
  28. }
  29. }

  Java中提供了一套API来处理JavaBean,也就是内省(Introspector)机制的核心,这些处理类位于java.beans目录下,下面我们来了解一下:

PropertyDescriptor类:

  Introduction:可以叫这个类作属性描述类,也就是可以通过这个类去描述我们想要操作的类。

  Methods:

    public PropertyDescriptor(String propertyName, Class<?> beanClass):propertyName就是JavaBean中的属性,像上面那样Person类中的“id”,beanClass就是JavaBean类了,像Person类,我们通过getClass方法就可以拿到该类的Class了,这个构造方法得到了该JavaBean的属性描述类。

    public Method getReadMethod():获取用于读取属性值的方法,例如通过这个方法就可以拿到“id”的getId方法。

    public Method getWriteMethod():获取用于写入属性值的方法,例如通过这个方法就可以拿到“id”的setId方法。

    注意:上面两个方法的返回值是Method,要操作方法的话需要通过invoke方法来调用。

  1. @SuppressWarnings("all")
  2. public class TestPropertyDescriptor {
  3.  
  4. private static Person person;
  5.  
  6. @BeforeClass
  7. public static void init() {
  8. person = new Person(1, "xujianguo");
  9. }
  10.  
  11. @Test
  12. public void testGetProperty() throws Exception {
  13. PropertyDescriptor pd = new PropertyDescriptor("id", person.getClass());
  14. Method method = pd.getReadMethod();
  15. Object id = method.invoke(person, null);
  16. System.out.println(id);
  17. }
  18.  
  19. @Test
  20. public void testSetProperty() throws Exception {
  21. PropertyDescriptor pd = new PropertyDescriptor("id", person.getClass());
  22. Method method = pd.getWriteMethod();
  23. method.invoke(person, 3);
  24. testGetProperty();
  25. }
  26. }

上面的testGetProperty方法可以拿到id的值,testSetProperty方法可以设置id的值,然后通过testGetProperty方法打印出id的值。

Introspector类:

  Introduction:Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。

  Method:

    public static BeanInfo getBeanInfo(Class<?> beanClass)在javabean上进行内省,了解该类的所有属性、方法和事件,所以这个方法很重要。这个方法的返回值是BeanInfo类型的,下面我们来看看这个类:

  BeanInfo类:

    Introduction:该类是一个可以提供JavaBean各种信息的类。

    Method:

      public PropertyDescriptor[] getPropertyDescriptors():获取bean的PropertyDescriptor,这个获取的是一个数组,数组里面装的是各种属性的属性描述类,通过该方法就可以找到我们想要操作的那个方法。

  1. @SuppressWarnings("all")
  2. public class TestPropertyDescriptor {
  3.  
  4. private static Person person;
  5.  
  6. @BeforeClass
  7. public static void init() {
  8. person = new Person(1, "xujianguo");
  9. }
  10.  
  11. @Test
  12. public void testOtherMethod() throws Exception {
  13. BeanInfo beanInfo = Introspector.getBeanInfo(person.getClass());
  14. PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
  15. Object value = null;
  16. for(PropertyDescriptor pd : pds) {
  17. if(pd.getName().equals("name")) {
  18. Method method = pd.getReadMethod();
  19. value = method.invoke(person, null);
  20. break;
  21. }
  22. }
  23. System.out.println(value);
  24. }
  25. }

上面的例子在一个属性描述类的数组中找到我们要操作的name的方法,PropertyDescriptor的getName方法可以拿到属性名。

下面介绍BeanUtils工具包:

BeanUtils就是一个小小的框架,里面封装很多方法,让我们很方便的调用,随心所欲的操作JavaBean。

  BeanUtils.PropertyUtils:是这个工具包里面很重要的一个类,这个类通过它的名字就可以知道它操作的是JavaBean的属性,在操作之前我们首先理解property的几种状态:

  Simple:也就是Java的基础类型,指property的属性修饰符,如int、String,这些都是比较简单的类型,我们就可以通过public static Object getSimpleProperty(Object bean, String name)方法拿到属性值,用public static Object setSimpleProperty(Object bean, String name, Object value)设置属性值。

  Indexed:这个属性的状态是针对List等集合的,如果属性修饰符是List的话,就可以通过public static Obejct getIndexedProperty(Object bean, String name, int index)方法拿到属性值,用public static Obejct setIndexedProperty(Object bean, String name, int index, Object value)方法设置属性值。

  Mapped:这个属性的状态是针对Map集合,因为Map的里面的设置是key-value的关系,PropertyUtils类就用这个方法的key去拿Map中的value,即是通过public static Object getMappedProperty(Obejct bean, String name, String value)方法去拿key对应的value,通过public static Object setMappedProperty(Object bean, String name, String value, Object value)方法去设置key对应的value。

  Nested:这个就是用来解决比较复杂的属性问题,如你的List里面放置了Person,但你想拿出Person中的name属性,怎么办呢?就是用这个方法了,通过public static Object getNestedProperty(Object bean, String name)拿出属性值,通过public static Object setNestedProperty(Object bean, String name, Object value)去设置它的属性值,但是你会说,这个跟前面的一样啊,哈哈,是的,这个方法的特定即使在写name的值的时候可以通过“.”符号来层层拿出值,看下面的例子你就知道了。

首先定义一个JavaBean类:

  1. @SuppressWarnings("rawtypes")
  2. public class School {
  3. private int id;
  4. private String name;
  5. private List list;
  6. private Map map;
  7. private List<Person> personList;
  8.  
  9. public int getId() {
  10. return id;
  11. }
  12. public void setId(int id) {
  13. this.id = id;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. public List getList() {
  22. return list;
  23. }
  24. public void setList(List list) {
  25. this.list = list;
  26. }
  27. public Map getMap() {
  28. return map;
  29. }
  30. public void setMap(Map map) {
  31. this.map = map;
  32. }
  33. public List<Person> getPersonList() {
  34. return personList;
  35. }
  36. public void setPersonList(List<Person> personList) {
  37. this.personList = personList;
  38. }
  39. }

下面就是测试类了:

  1. @SuppressWarnings("all")
  2. public class BeanUtilsDemo {
  3.  
  4. private static School school;
  5.  
  6. @Before
  7. public void initing() {
  8. school = new School();
  9. school.setId(1);
  10. school.setName("gdut");
  11.  
  12. List list = new ArrayList();
  13. list.add("first");
  14. list.add("second");
  15. school.setList(list);
  16.  
  17. Map map = new HashMap();
  18. map.put("xjg", "xujianguo");
  19. map.put("zyp", "zhouyanping");
  20. school.setMap(map);
  21.  
  22. Person person = new Person(3, "RayGuo");
  23. List<Person> personList = new ArrayList<Person>();
  24. personList.add(person);
  25. school.setPersonList(personList);
  26. }
  27.  
  28. @Test
  29. public void testSimpleGetProperty() throws Exception, NoSuchMethodException {
  30. int id = (Integer) PropertyUtils.getSimpleProperty(school, "id");
  31. String name = (String) PropertyUtils.getSimpleProperty(school, "name");
  32. System.out.println(id + " " + name);
  33. }
  34.  
  35. @Test
  36. public void testSimpleSetProperty() throws Exception {
  37. PropertyUtils.setSimpleProperty(school, "id", 2);
  38. PropertyUtils.setSimpleProperty(school, "name", "scut");
  39. testSimpleGetProperty();
  40. }
  41.  
  42. @Test
  43. public void testIndexedGetProperty() throws Exception {
  44. String str = (String) PropertyUtils.getIndexedProperty(school, "list", 1);
  45. System.out.println(str);
  46. }
  47.  
  48. @Test
  49. public void testIndexedSetProperty() throws Exception {
  50. PropertyUtils.setIndexedProperty(school, "list", 1, "secondsecond");
  51. testIndexedGetProperty();
  52. }
  53.  
  54. @Test
  55. public void testMappedGetProperty() throws Exception {
  56. String name = (String) PropertyUtils.getMappedProperty(school, "map", "zyp");
  57. System.out.println(name);
  58. }
  59.  
  60. @Test
  61. public void testMappedSetProperty() throws Exception {
  62. PropertyUtils.setMappedProperty(school, "map", "zyp", "zypzyp");
  63. testMappedGetProperty();
  64. }
  65.  
  66. @Test
  67. public void testNestedGetProperty() throws Exception {
  68. String name = (String) PropertyUtils.getNestedProperty(school, "personList[0].name");
  69. System.out.println(name);
  70. }
  71.  
  72. @Test
  73. public void testNestedSetProperty() throws Exception {
  74. PropertyUtils.setNestedProperty(school, "personList[0].name", "ApplePing");
  75. testNestedGetProperty();
  76. }
  77. }

  

  BasicDynaClass和BasicDynaBean:两个类是挺好用的东西来的,比如说你会遇到这种情况,从数据库拿到了一堆的数据,但是你不想写一个Class,也就是定义一个实体类,这个我们可以采用这个类了,就是动态生成一个JavaBean,用这个JavaBean来操作这些数据,存储这些数据,就不用写死一个Class了,下面我们来简单了解一下怎么用:

    DynaProperty类:从名字就可以知道了,动态属性,就是定义一个动态类有哪些属性了

      method:public DynaProperty(String name, Class type):这是构造方法,通过该构造方法就可以创建一个动态的属性了

    BasicDynaClass类:这个就是动态类了,通过这个类创建一个我们需要的动态类,在创建的时候当然要我们前面定义的动态属性加进入了。

      method:

        public BasicDynaClass(String name, Class dynaBeanClass, DynaProperty[] props):这个是它的构造方法,name是你要动态生成那个JavaBean的名字,dynaBeanClass就是指这个类的Class类型,props就是JavaBean的属性集合了。

        public DynaBean newInstance():通过这个方法就可以创建一个实例了。

    DynaBean类:动态的JavaBean

      method:

        Object set(String name, Object value):设置属性的值

        Object get(String name):得到属性的值

Demo:

  1. @SuppressWarnings("rawtypes")
  2. public class DynaClassDemo {
  3.  
  4. @Test
  5. public void test() throws Exception {
  6. DynaProperty prop1 = new DynaProperty("id", Integer.class);
  7. DynaProperty prop2 = new DynaProperty("name", String.class);
  8. DynaProperty prop3 = new DynaProperty("map", java.util.Map.class);
  9. DynaProperty[] prop = new DynaProperty[]{prop1, prop2, prop3};
  10.  
  11. BasicDynaClass dynaClass = new BasicDynaClass("people", null, prop);
  12. DynaBean people = dynaClass.newInstance();
  13. people.set("id", 1);
  14. people.set("name", "xujianguo");
  15. people.set("map", new HashMap());
  16.  
  17. System.out.println(people.get("id") + " " + people.get("name"));
  18. }
  19. }

      

      

  

Java内省的更多相关文章

  1. JAVA内省(Introspector)

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

  2. java 内省

    用内省来操作Bean会给程序带来很大的便利,特别是在很大的实体对象的时候,在其属性很多的时候要为其赋值的时候, package com.bean; public class User { privat ...

  3. Java内省机制

    转自: https://blog.csdn.net/hahalzb/article/details/5972421 1.java内省机制其实通俗的理解为,对自身的进行一个扫描,这个扫描的对象就是我们普 ...

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

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

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

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

  6. Java 内省(Introspector)和 BeanUtils

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

  7. Java基础扫盲系列(三)— Java内省技术

    前言 Java内省技术属于Java基础体系的的一部分,但是很多人都不甚了解.笔者也是在学习Spring源码的过程中遇到该技术模块的.为了完善技术体系,本文将全面的学习该技术.在提到Java内省技术,就 ...

  8. java内省机制及PropertyUtils使用方法

    背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...

  9. java内省机制Introspector

    访问JavaBean属性的两种方式 1)直接调用bean的setXXX或getXXX方法: 2)通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式: a)通过P ...

随机推荐

  1. hbase on spark

    1.在spark的伪分布式环境下安装HBASE (1)版本:我使用的spark版本是1.3.0,使用的hbase版本是hbase-0.94.16 (2)解压,tar zxvf  hbase-0.94. ...

  2. WPF如何卸载U盘(弹出USB设备)

    应用程序和硬件设备的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl()与硬件设备通信. CreateFile函数: [DllImport("k ...

  3. [翻译]15个最常见的WCF面试问题

    WCF和ASMX WebService的区别是什么? 最基本的区别在于,ASMX或者ASP.NET WebService是用来通过基于HTTP的SOAP来实现通讯.但WCF可以使用任意协议(HTTP, ...

  4. Java 动态代理(转载)

    JAVA的动态代理  代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后 处理消息等.代理类与 ...

  5. 在虚拟中开启Windows 8.1的Hyper-V平台

    VM安装windows8开启Hype-V 今天老魏用VM安装了Windows8.1系统,想用此系统来开发一下Windows Phone8,但是要求确实要开启Hyper-V平台技术,本来是没有任何的问题 ...

  6. Python拷贝及多进程与类的问题

    最近写python写的尤其不顺利,更多的debug,逐渐的深入,产出却比较少.应该是个瓶颈期,坚持坚持,厚着脸皮也要坚持下去. 0x00 拷贝问题 程序中涉及到多进程和协程,大致的模型是开了2+个进程 ...

  7. DB天气 Alpha版使用说明

    一 产品介绍 DB天气是一款能够准确预报天气的软件,它的特点在于它的简洁的设计风格,以及贴心的预报方式.是一款非主流的小清新的天气APP. 二 功能介绍 下面介绍一下DB天气的主界面以及天气功能的实现 ...

  8. github简单使用

    github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.对于一般人来说公共仓库就已经足够了,而且我们也没多少代码来管理,O(∩_∩)O ...

  9. JavaScript中创建字典对象(dictionary)实例

    这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...

  10. Eclipse console文本换行

    Eclipse换行主要有3个方面 格式化时编辑器文本换行 源代码注释文本换行 Eclipse控制台console显示文本换行 1和2参考 http://hi.baidu.com/ae6623/item ...