Java 内省机制

男娘i 2024-04-18 19:41 175阅读 0赞

一、内省机制概述

  1. Java中的反射机制是通过名称得到类的方法和对象的成份,对于一切Java类都是适用的,但是有时候使用起来比较麻烦。而JavaBean是一种特殊的Java类,遵守JavaBean的规范,即所有的成员都是私有成员,且每个成员都有公开的读取和设定的方法(gettersetter),且这些方法都遵守命名的规范。就是因为JavaBean有这些的特性,sun推出了一种专门对JavaBean成员进行访问的技术,方便对其的访问,就是内省技术。
  2. 即:通过内省机制(自省机制)可以获取和操作JavaBean中的成员信息(方法,事件和属性)。.

JavaBean规范:

什么是JavaBean:符合某些设计规范的类。使用JavaBean,可避免代码重复问题,起到功能重复使用。

  1. 1)类必须使用public修饰
  2. 2)必须保证有公共无参数的构造器
  3. 3)包含属性(property)的操作手段(getter/setter方法)
  4. JavaBean包含的成员:method方法、event事件或property属性

1、内省和反射有什么区别?

  1. 反射(Reflect)是在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。
  2. 内省(IntroSpector)是Java 语言对 Bean 类属性、事件的一种缺省处理方法。内省机制是通过反射来实现的

2、内省机制的作用

用于查看和操作JavaBean中的属性:

  1. 1)获取JavaBean中的每一个属性名/属性类型
  2. 2)通过getter方法获取属性值,通过setter方法给属性设置值

3、内省机制中使用到的核心几个类,列举几个常用方法,具体查看API

  1. ** 1java.beans.Introspector类**
  2. Introspector相当于一个工具类,提供了一种标准的工具来了解目标JavaBean支持的属性,事件和方法,即一系列取得Bean信息的方法。











    • static BeanInfo getBeanInfo(Class<?> beanClass)

      内省Java Bean并了解其所有属性,暴露的方法和事件。

      static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass)

      内省Java bean并了解其属性,暴露的方法,低于给定的“停止”点。

    2)java.beans.BeanInfo接口

    1. beanInfo接口是对一个Bean的描述,可以通过它取得Bean内部的信息。
  • 3)java.beans.PropertyDescriptor类

    1. PropertyDescriptor类是对一个Bean属性的描述,它提供了一系列对Bean属性进行操作的方法。
  • java.beans.FeatureDescriptor类是PropertyDescriptor,EventSetDescriptor和MethodDescriptor等的常见基类(父类)。

    它支持一些可以为任何内省描述符设置和检索的常见信息

二、demo

  1. public class User {
  2. private Long id;
  3. private String username;
  4. private Integer age;
  5. private Long account;
  6. public User() {
  7. }
  8. gettersettertoString 方法
  9. }

1、通过内省机制获取JavaBean属性值和属性设值

  1. @Test
  2. public void testIntrospector() throws Exception {
  3. User user = User.class.newInstance();
  4. user.setId(111L);
  5. // 获取JavaBean的描述对象BeanInfo
  6. //BeanInfo beanInfo = Introspector.getBeanInfo(User.class); // 包含父类的,比如:getClass()
  7. BeanInfo beanInfo = Introspector.getBeanInfo(User.class, Object.class); // 不包含父类的
  8. // 获取JavaBean中所有属性的描述器对象PropertyDescriptor
  9. PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
  10. for (PropertyDescriptor pd : pds) {
  11. // 获取当前属性的名称
  12. String name = pd.getName();
  13. if("id".equals(name)){
  14. // 调用getter方法,获取属性值
  15. Object value = pd.getReadMethod().invoke(user);
  16. System.out.println(value); // 111
  17. }
  18. if("username".equals(name)){
  19. // 获取当前属性的数据类型
  20. Class<?> propertyType = pd.getPropertyType();
  21. System.out.println(propertyType); //class java.lang.String
  22. // 调用setter方法,设置属性值
  23. pd.getWriteMethod().invoke(user,"赵云");
  24. }
  25. if("age".equals(name)){
  26. pd.getWriteMethod().invoke(user,17);
  27. }
  28. }
  29. System.out.println(user); //User{id=null, username='赵云', age=17, account=null}
  30. }

2、JavaBean与Map之间的相互转换

  1. //JavaBean对象转Map<String,Object>
  2. public Map<String,Object> bean2map(Object bean) throws Exception {
  3. Map<String,Object> map = new HashMap<>();
  4. BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
  5. PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
  6. for (PropertyDescriptor pd : pds) {
  7. String name = pd.getName();
  8. Object value = pd.getReadMethod().invoke(bean);
  9. map.put(name,value);
  10. }
  11. return map;
  12. }
  13. //Map<String,Object>转JavaBean对象
  14. public <T> T map2bean(Map<String,Object> map, Class<T> clazz) throws Exception {
  15. T t = clazz.newInstance();
  16. BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
  17. PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
  18. for (PropertyDescriptor pd : pds) {
  19. Object value = map.get(pd.getName());
  20. pd.getWriteMethod().invoke(t,value);
  21. }
  22. return t;
  23. }
  24. @Test
  25. public void testChange() throws Exception {
  26. User user = new User();
  27. user.setUsername("赵云");
  28. user.setAge(17);
  29. Map<String, Object> map = bean2map(user);
  30. System.out.println(map); // {id=null, account=null, age=17, username=赵云}
  31. map.put("account",1000L);
  32. Class<User> userClass = User.class;
  33. User user1 = map2bean(map, userClass);
  34. System.out.println(user1);// User{id=null, username='赵云', age=17, account=1000}
  35. }

总结:

  1. 1、使用内省机制对JavaBean属性进行操作还是很复杂的,一些第三方组织封装了某些工具类来方便开发者使用,如:

org.apache.commons.beanutils.BeanUtils是apache封装的工具类,用来解决使用内省机制繁琐的问题,包含了挺多方法。

使用时要导入两个包:commons-beanutils-xx.jar和commons-logging-xx.jar。

  1. 2、将 Java的反射以及内省应用到程序设计中去可以大大的提供程序的智能化和可扩展性。有很多项目或者框架都是采取这两种技术来实现其核心功能。比如Struts2SpringMVC
  2. 这些框架只要在.action中,或者controller方法的形参处,引入JavaBean就可以实例化这个JavaBean的值,并且可以获得表单提交的数据,那么它究竟是怎么得到的呢?
  3. 其实就是 request.getParameterMap() 获取得到表单提交来的所有键值对,只不过框架内部封装了,然后框架内部利用内省,将数据封装到JavaBean中。
  4. 3Java的反射以及内省机制重点掌握,查阅框架源码时多加留意,理解其中的设计重构封装等思想
  5. 站在前辈的肩膀上,每天进步一点点

ends~

发表评论

表情:
评论列表 (有 0 条评论,175人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java 内省机制

    一、内省机制概述         Java中的反射机制是通过名称得到类的方法和对象的成份,对于一切Java类都是适用的,但是有时候使用起来比较麻烦。而JavaBean...

    相关 Java反射与内省

    反射 用一句比较白的话来概括,反射就是让你可以通过名称来得到对象(类,属性,方法)的技术。 例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了

    相关 java 内省机制

    什么是内省: 官方: 内省(Introspector)是Java语言对Bean类属性、事件的一种缺省处理方法。 个人理解: 说白了就是通过反

    相关 JAVA中的内省

    [为什么80%的码农都做不了架构师?>>> ][80_] ![hot3.png][] 为了让程序员们更好的操作Java对象的属性,SUN公司开发了一套API,被业界内称为:内

    相关 Java内省机制

    1).内省(Introspector)是Java 语言对Bean类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setN...