小记
在Java中导入java.lang.reflect.Field;
java.lang.reflect.Method;
这两个包
可以定义Field
(表示类任意数据类型的属性)和Method
(表示类方法)的变量
导入java.lang.reflect.Constructor;
包
可定义Constructor
(表示构造方法)的变量
快捷键
ctrl+alt+v
可在数据左边创建变量
如:
用完快捷键变成:
Java内存
有如下三种
类的加载过程
- 首先,当源代码文件编译为
class
文件后,系统就会将类的class
文件读入内存中,并为之创建一个java.lang.Class
对象。此过程由类加载器完成。 - 然后,系统会把类的二进制数据合并到JRE中。
- 最后,JVM负责对类进行初始化
具体如下:其中需要注意的就是
<clinit>()
方法
还有类的初始化
类的初始化
什么时候会发生类的初始化?
这些即类的主动引用
什么时候不会发生类的初始化?
类加载器
类加载器的作用:
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。
类缓存:
标准的JavaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存) - -段时间。不过JVM垃圾回收机制可以回收这些Class对象。
类加载器的一些类型
获得类的运行时结构
类的运行时结构指的就是类的属性,方法,构造方法,父类…
- 获得类名:
getName方法获得类的包名,getSimpleName方法获得类名
- 获得属性
Field[]创建了一个可以用来存储属性的数组
获得指定属性的值
这里也需要抛出异常
- 获得类的方法
Method[]定义了一个用来存放方法类型的数组
获得指定的方法:
即我们获得我们想要的方法,需要传入对应的函数名和参数数据类型名
- 获得构造方法:
Constructor用于创建一个存储构造方法的变量,同样需要抛出异常
通过Class来使用类中的构造方法、属性、方法
通过Class创建对象
- 我们可以通过调用Class对象的
newInstance()
已弃用方法,来调用对应的类的无参的公有的构造方法来创建对象。
这个方法只能自动调用对应的类的无参的公有的构造方法
- 先获得构造方法,再通过获得的构造方法进行创建对象,这里要用到
Constructor
的newInstance
对象
这里的
getConstructor
方法也是只能获得public
修饰的构造方法,不过,如果构造方法是用private
修饰的,则可以用getDeclaredConstructor()
方法获得构造方法
通过Class使用类的方法
- 获得对应的方法,这里也一样,当方法是
private
修饰的时候,可以调用Class类的getDeclaredMethod
来得到对应的方法 - 激活使用方法,通过
invoke
方法,他需要传入参数,第一个是需要使用获得的方法的对象,其余的为获得的方法需要传入的参数,他的作用就是在传入的第一个参数对象中调用他的对应的方法
通过Class调用和使用类的属性
- 首先需要获得对应的属性,因为User中的name属性是用private修饰的,所以我们也要使用加了
Declared
的getField
方法,即getDeclaredField
,和前面说的几个一样,只要是私有的则可以在get后面加上Declared
就行 - 因为name属性是私有的,所以我们不能直接设置,在设置之前,我们需要先通过Class关闭“权限检测”,通过
setAccessible
这样的一个方法,无论是字段还是方法,都有这样一个方法setAccessible
这样的一个方法,可以去控制权限,他的中文翻译正好是"设置可访问",所以我们需要传入参数true
才可以设置可访问权限,即关闭权限检测 - 通过Class设置name属性值,这里用到类属性的set方法,需要传入两个参数,第一个是需要设置的对象,第二个为对应的属性值