浅谈Java内省(java内存详解)

createh53个月前 (02-01)技术教程36

作者:京东物流 王国泰

一、什么是内省

  • 讲内省,不得不说Java Bean,Bean在Java中是一种特殊的类,主要用于装载数据,数据会被存储在类的私有属性中,通常具有无参构造函数、可序列化、以及通过getter和setter方法来访问属性。内省是Java Beans规范的一部分,使用java.beans包中的类来实现,最常用的类是Introspector。通过内省,你可以获取一个Java Bean的属性描述符(PropertyDescriptor)和方法描述符(MethodDescriptor)

二、内省常用API

1、相关类

2、Introspector

2.1 核心功能

  • 用于获取Bean的整体信息,包括属性描述符、方法描述符和事件描述符等

2.2 核心方法

  • getBeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(Vehicle.class);

3、BeanInfo

3.1 核心功能

  • 用于提供有关Bean的元数据,通常用于描述Bean的属性、事件和方法

3.2 核心方法

  • getPropertyDescriptors
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
  • getMethodDescriptors
MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
  • getEventSetDescriptors
EventSetDescriptor[] eventSetDescriptors = beanInfo.getEventSetDescriptors();

4、PropertyDescriptor

4.1 核心功能

  • 用于描述Bean的属性,提供了对属性的详细描述,包括属性的名称、类型、读方法getter、写方法setter等

4.2 核心方法

  • getName
PropertyDescriptor namePD = new PropertyDescriptor("name", Vehicle.class);
String name = namePD.getName();
  • getReadMethod
PropertyDescriptor namePD = new PropertyDescriptor("name", Vehicle.class);
Method getter = namePD.getReadMethod();

String methodName = getter.getName();
String vehicleName = (String) getter.invoke(new Vehicle());
  • getWriteMethod
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
MethodDescriptor methodDescriptor = new MethodDescriptor(Vehicle.class.getMethod("setName", String.class));
String name = methodDescriptor.getName();
  • getMethod
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,部分源码如下:
@Override
public PropertyDescriptor[] getPropertyDescriptors() {
  return getCachedIntrospectionResults().getPropertyDescriptors();
}

2、对象拷贝

  • Spring BeanUtils使用内省来复制对象的属性,可参考BeanUtils,部分源码如下:
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

相关文章

Python之面向对象:私有属性是掩耳盗铃还是恰到好处

引言声明,今天的文章中没有一行Python代码,更多的是对编程语言设计理念的思考。上一篇文章中介绍了关于Python面向对象封装特性的私有属性的相关内容,提到了Python中关于私有属性的实现是通过“...

java匿名内部类的定义以及使用场景

匿名内部类定义 匿名内部类是Java中一种没有显式声明名称的内部类。它们在创建时被同时声明和实例化,通常用于创建一次性使用的类。它们的特点是:无名称: 无法像普通类一样被其他代码引用。一次性: 通常只...

Java设计模式-单例模式(java单例模式原理)

单例模式定义:它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式主要分为两大类:饿汉式和懒汉式,懒汉式又分为 单线程下的普通懒汉式,多线程下的双重校验锁、静态内部类、枚举。单例模式的...

终于搞懂了 Java 8 的内存结构,再也不纠结方法区和常量池了

java8内存结构图虚拟机内存与本地内存的区别Java虚拟机在执行的时候会把管理的内存分配成不同的区域,这些区域被称为虚拟机内存,同时,对于虚拟机没有直接管理的物理内存,也有一定的利用,这些被利用却不...

java的53个关键字(含2个保留字)第一篇

1.java的关键字(keyword)有多少个? 51+2个保留字=53个关键字(java的关键字都是小写的!!)2.java的保留字(reserve word)有多少个?问题:分别是什么? 1).c...

做开发这么久了,还不会搭建服务器Maven私有仓库?这也太Low了吧

大家好,我是冰河~~最近不少小伙伴想在自己公司的内网搭建一套Maven私服环境,可自己搭建的过程中,或多过少的总会出现一些问题,问我可不可以出一篇如何搭建Maven私服的文章。这不,就有了这篇文章嘛。...