一、堆内存中的情况
(一)对象创建与变化
- 源对象(UserBo)和目标对象(User)
- 在执行
UserBo sourceObj = new UserBo(username, password);
和User targetObj = new User();
时,分别在堆内存中创建了UserBo
和User
的实例对象。这些对象占用一定的堆空间,用于存储对象的实例变量。 - 在
TianBeanUtil.copy
方法执行过程中,这两个对象本身在堆中的存储位置不变,但它们内部的实例变量可能会被修改(如果目标对象的相应字段存在且赋值成功)。
- 在执行
- 反射相关临时对象
- 当执行
Class<?> sourceClass = sourceObj.getClass();
和Class<?> targetClass = targetObj.getClass();
时,会在堆内存中创建Class
对象(如果之前没有创建过)。这些Class
对象用于表示源对象和目标对象的类信息,包含类的元数据,如类的方法、字段等信息的引用。 - 在
Field[] fields = sourceClass.getDeclaredFields();
语句执行时,会在堆内存中创建一个Field
数组对象。这个数组的每个元素都是一个Field
对象,用于表示源对象类中的一个字段。每个Field
对象包含了字段的名称、类型等信息。
- 当执行
(二)垃圾回收
- 如果在执行
TianBeanUtil.copy
方法过程中创建了一些临时变量(如在异常处理块中可能创建的临时对象),当这些变量超出作用域时,它们所占用的堆内存会在合适的时候被垃圾回收器回收。例如,如果在catch
块中创建了表示异常信息的临时对象,当catch
块执行完毕后,这些对象就可能被回收。
二、方法区中的情况
(一)类加载与字节码信息
- 源对象和目标对象类信息
- 在创建
UserBo
和User
对象时(如果是首次使用这些类),它们的类字节码信息会被加载到方法区。这些字节码信息包含了类的结构,如类的常量池、方法字节码、字段描述等。 - 在
TianBeanUtil.copy
方法执行过程中,当通过反射访问类的字段和方法时,JVM会从方法区中的类字节码信息中获取相关数据。例如,sourceClass.getDeclaredFields()
会根据方法区中sourceObj
所属类(UserBo
)的字节码信息获取所有声明的字段信息。
- 在创建
- 反射相关类信息
- 由于代码中使用了
java.lang.Class
和java.lang.reflect.Field
等反射相关的类,这些类的字节码信息在方法区中是预先存在的(作为Java核心库的一部分)。当执行反射操作时,会从方法区中获取这些类的方法字节码来执行操作,如getDeclaredField
、setAccessible
、get
和set
等方法的字节码指令会从方法区中获取并执行。
- 由于代码中使用了
(二)常量池相关
- 在方法执行过程中,如果涉及到字符串常量(如字段名等),这些字符串常量的引用会从方法区的常量池中获取。例如,
String name = sourceField.getName();
语句获取的字段名是从方法区常量池中读取的字符串常量。