反射定义
1,JAVA反射机制是在运行状态中
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射提供的功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
**(如果属性是private,正常情况下是不允许外界操作属性值,这里可以用Field类的setAccessible(true)方法,暂时打开操作的权限)**
反射的使用场景
- Java编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射
- 如果编码时不知道类或者对象的具体信息,此时应该使用反射来实现
反射源码解析
举例API :
1 | scss复制代码Class.forName("com.my.reflectTest").newInstance() |
1. 反射获取类实例 Class.forName(“xxx”);
首先调用了 java.lang.Class 的静态方法,获取类信息!
注意:forName()反射获取类信息,并没有将实现留给了java,而是交给了jvm去加载!
主要是先获取 ClassLoader, 然后调用 native 方法,获取信息,加载类则是回调 入参ClassLoader 进类加载!
1 | swift复制代码 @CallerSensitive |
2. java.lang.ClassLoader—–loadClass()
1 | scss复制代码// java.lang.ClassLoader |
3. newInstance()
1 | scss复制代码newInstance() 其实相当于调用类的无参构造函数,主要做了三件事 |
- 权限检测,如果不通过直接抛出异常;
- 查找无参构造器,并将其缓存起来;
- 调用具体方法的无参构造方法,生成实例并返回;
1 | kotlin复制代码// 首先肯定是 Class.newInstance |
4. getConstructor0() 为获取匹配的构造方器;分三步:
1. 先获取所有的constructors, 然后通过进行参数类型比较;
2. 找到匹配后,通过 ReflectionFactory copy一份constructor返回;
3. 否则抛出 NoSuchMethodException;
1 | scss复制代码private Constructor<T> getConstructor0(Class<?>[] parameterTypes, |
5. privateGetDeclaredConstructors(), 获取所有的构造器主要步骤;
1. 先尝试从缓存中获取;
2. 如果缓存没有,则从jvm中重新获取,并存入缓存,缓存使用软引用进行保存,保证内存可用;
1 | kotlin复制代码// 获取当前类所有的构造方法,通过jvm或者缓存 |
另外,使用 relactionData() 进行缓存保存;ReflectionData 的数据结构如下!
1 | ini复制代码// reflection data that might get invalidated when JVM TI RedefineClasses() is called |
6.通过上面,获取到 Constructor 了!接下来就只需调用其相应构造器的 newInstance(),即返回实例了!
1 | scss复制代码// return tmpConstructor.newInstance((Object[])null); |
返回构造器的实例后,可以根据外部进行进行类型转换,从而使用接口或方法进行调用实例功能了。
总结
欢迎关注公众号:前程有光,领取一线大厂Java面试题总结+各知识点学习思维导+一份300页pdf文档的Java核心知识点总结!
这些资料的内容都是面试时面试官必问的知识点,篇章包括了很多知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。
本文转载自: 掘金