反射¶
定义¶
比如,IDEA自动补全,怎么知道某个对象有哪些方法的?答案是利用反射.
如果没有反射,想要从某个源文件获得类的成员信息,那么就需要一些类似于静态分析的方法.
获取class对象¶
其中第一种方式是从class/源代码文件中获得的.
第二种是加载到内存时获得的
第三种是运行时获得的
示例¶
第一种最常用
第二种往往当参数使用.如synchronize中传递锁对象的代码.
第三种只有当我们有这个类的对象时才可以使用.
获取构造方法对象Constructor¶

示例¶

剖析¶
获得权限修饰符¶
返回的是一个int.
因此,public返回的是1
获得参数¶

创建对象¶
但是,如果这个构造是私有的,那么会抛异常.因此,如果想要调用私有的:
这种方式叫做暴力反射
获得成员变量对象Field¶

获取所有成员变量¶

获取单个成员变量¶

获取/修改的成员变量的值.¶
获取成员变量的名字,修饰符这些都不需要对象.但是获取值是需要的.
注意,需要先获得field对象,从该对象的.get方法获得值.
注意,如果是私有的,那么要setaccessible.
修改也是同理的:

获取成员的方法Method¶

示例¶
注意,还得设置visiable
还能获取异常
还能invoke(这个重要)

反射的作用¶

保存对象¶

配置文件+动态创建对象¶
这是配置文件:

动态代理¶
如果要给一段已经写好的代码修改,这是侵入式的,会很危险.因此,我们可以使用代理.
代理是非侵入式的,是可以给已有的代码添加功能的.
对象有什么方法想被代理,那么就需要代理有对应的方法.
那么有哪些方法需要被代理呢?我们可以把所有需要代理的方法写到接口里.
代理类和原先的类都需要实现中间的接口.

代码示例¶
原本的:¶
写成重写的:

代理之后¶
第一个参数:谁帮我们加载当前类的,就让它来加载.这个格式一般是固定的.
第二个参数:代理可以代理哪些接口.我们目前只有一个,因此放一个就行.
我们希望这样调用:
这里的参数1一般不用.

执行过程: 调用sing方法时,会自动调用我们之前注册的invoke方法.我们只关注后面两个参数.其中mothod的参数对应的就是sing方法,因此就执行if分支.