您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
浅谈Java内省
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
浅谈Java内省
jd_509a9e0341dbb
2024-12-17
IP归属:北京
100浏览
## 一、什么是内省 * 讲内省,不得不说Java Bean,Bean在Java中是一种特殊的类,主要用于装载数据,数据会被存储在类的私有属性中,通常具有无参构造函数、可序列化、以及通过getter和setter方法来访问属性。内省是Java Beans规范的一部分,使用java.beans包中的类来实现,最常用的类是Introspector。通过内省,你可以获取一个Java Bean的属性描述符(PropertyDescriptor)和方法描述符(MethodDescriptor) ## 二、内省常用API ### 1、相关类 ![](https://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2024-11-30-21-03aqc21grD0VXsxQEl.jpg) ### 2、Introspector #### 2.1 核心功能 * 用于获取Bean的整体信息,包括属性描述符、方法描述符和事件描述符等 #### 2.2 核心方法 * getBeanInfo ```java BeanInfo beanInfo = Introspector.getBeanInfo(Vehicle.class); ``` ### 3、BeanInfo #### 3.1 核心功能 * 用于提供有关Bean的元数据,通常用于描述Bean的属性、事件和方法 #### 3.2 核心方法 * getPropertyDescriptors ```java PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); ``` * getMethodDescriptors ```java MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors(); ``` * getEventSetDescriptors ```java EventSetDescriptor[] eventSetDescriptors = beanInfo.getEventSetDescriptors(); ``` ### 4、PropertyDescriptor #### 4.1 核心功能 * 用于描述Bean的属性,提供了对属性的详细描述,包括属性的名称、类型、读方法getter、写方法setter等 #### 4.2 核心方法 * getName ```java PropertyDescriptor namePD = new PropertyDescriptor("name", Vehicle.class); String name = namePD.getName(); ``` * getReadMethod ```java PropertyDescriptor namePD = new PropertyDescriptor("name", Vehicle.class); Method getter = namePD.getReadMethod(); String methodName = getter.getName(); String vehicleName = (String) getter.invoke(new Vehicle()); ``` * getWriteMethod ```java PropertyDescriptor namePD = new PropertyDescriptor("name", Vehicle.class); Method setter = namePD.getWriteMethod(); String methodName = setter.getName(); setter.invoke(new Vehicle(), "JD0001"); ``` ### 5、MethodDescriptor #### 5.1 核心功能 * 用于描述一个方法的属性,提供了对方法的详细描述,包括方法的名称、参数类型、返回类型等 #### 5.2 核心方法 * getName ```java MethodDescriptor methodDescriptor = new MethodDescriptor(Vehicle.class.getMethod("setName", String.class)); String name = methodDescriptor.getName(); ``` * getMethod ```java MethodDescriptor methodDescriptor = new MethodDescriptor(Vehicle.class.getMethod("setName", String.class)); Method method = methodDescriptor.getMethod(); method.invoke(new Vehicle(), "JD0001"); ``` ### 6、EventSetDescriptor #### 6.1 核心功能 * 用于描述一个Bean能够触发的一组事件,提供了有关事件监听器类型、添加和移除监听器的方法以及事件通知方法的信息 #### 6.2 核心方法 * 不常用 ## 三、内省常见使用场景 ### 1、依赖注入 * Spring使用内省来分析类的构造函数、字段和方法,并自动注入依赖对象,可参考BeanWrapperImpl,部分源码如下: ```java @Override public PropertyDescriptor[] getPropertyDescriptors() { return getCachedIntrospectionResults().getPropertyDescriptors(); } ``` ### 2、对象拷贝 * Spring BeanUtils使用内省来复制对象的属性,可参考BeanUtils,部分源码如下: ```java public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws BeansException { return CachedIntrospectionResults.forClass(clazz).getPropertyDescriptors(); } ``` ### 3、开发工具和IDE * 开发工具和集成开发环境(IDE,如IntelliJ IDEA)使用内省来提供代码补全、重构、调试等功能 ## 四、内省优缺点 ### 1、优点 * **灵活性和可扩展性**:允许在运行时动态地获取和操作对象的属性和方法 * **简化开发工作**:支持框架和工具的开发,能够自动处理对象的属性和方法 ### 2、缺点 * **性能开销**:比直接调用方法或访问字段要慢,而且不当使用可能会导致内存泄漏或增加GC压力 * **访问安全**:绕过Java的访问控制机制,访问私有字段和方法,可能会带来安全隐患,特别是在处理敏感数据时 * **类型安全**:通常是基于字符串名称进行的(如方法名、属性名),在编译时无法检查其正确性,容易导致运行时错误 * **可读性和可维护性**:代码可读性差,增加调试难度 ## 五、内省与反射的区别 ### 1、用途 * 内省主要用于Java Bean的属性操作,适合于标准化的Bean操作 * 反射则是更通用的机制,可以操作类的所有成员,包括私有成员 ### 2、实现 * 内省是基于Java Beans规范的,使用java.beans包 * 反射是Java语言的核心特性,使用java.lang.reflect包 ### 3、性能 * 内省通常比反射快,主要原因是内省使用了缓存机制,减少了权限检查,并且在设计上针对特定场景进行了优化 ## 相关文献 * JavaBeans API Specification:https://docs.oracle.com/javase/8/docs/api/java/beans/package-summary.html * 《Java编程思想》(Thinking in Java) - Bruce Eckel * 《Java核心技术 卷 I》(Core Java Volume I) - Cay S. Horstmann, Gary Cornell * 《Java反射机制详解》(Java Reflection in Action) - Ira R. Forman, Nate Forman
上一篇:java小知识-ShutdownHook(优雅关闭)
下一篇:MySQL存储引擎及索引简介
jd_509a9e0341dbb
文章数
1
阅读量
0
作者其他文章
01
浅谈Java内省
一、什么是内省讲内省,不得不说Java Bean,Bean在Java中是一种特殊的类,主要用于装载数据,数据会被存储在类的私有属性中,通常具有无参构造函数、可序列化、以及通过getter和setter方法来访问属性。内省是Java Beans规范的一部分,使用java.beans包中的类来实现,最常用的类是Introspector。通过内省,你可以获取一个Java Bean的属性描述符(Prope
jd_509a9e0341dbb
文章数
1
阅读量
0
作者其他文章
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号