JAVA反射机制
JAVA在JDK1.5之后引入了反射机制,通过反射,使得我们在程序运行时可以动态根据方法名实现调用,可以便利对象属性、在我们不知道具体某个对象的类型时可以通过反射获取等等。其实这些一个最基本的作用和就是内省。
下面这个脑图是在网上拿到的:
比较常见用法:
package practice.base;
import com.hbnnmall.hbnnmallproduct.dto.GoodsDetailRequest;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReflectionPra {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, IntrospectionException, InvocationTargetException {
GoodsDetailRequest goodsDetailRequest = new GoodsDetailRequest();
goodsDetailRequest.setGid(244L);
Class<?> cl = goodsDetailRequest.getClass();
System.out.println(cl.getName());
System.out.println(cl.getClassLoader());
System.out.println(Arrays.toString(cl.getDeclaredConstructors()));
System.out.println(Class.forName("com.hbnnmall.hbnnmallproduct.dto.GoodsDetailRequest"));
Field[] fields = cl.getDeclaredFields();
System.out.println(Arrays.toString(fields));
//遍历属性
for (Field field:fields){
field.setAccessible(true);
System.out.println(field.getName());
System.out.println(field.get(goodsDetailRequest));
PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), cl);
Method method = descriptor.getReadMethod();
Object value = method.invoke(goodsDetailRequest);
System.out.println(value);
}
}
}
JAVA反射主要是通过类Class对象 和java.lang.reflect实现的。
1、Class
对于JAVA来讲,在编译时,会将我们写的程序编译成字节码,JVM的类加载器会读取字节码文件(.class)文件,随后会经历验证解析等阶段,具体的可以看我之前写的文章: JAVA类加载以及SPI机制
CLass对象作为元信息会被存储在方法区。
当我们在执行一个对象创建时,比如
GoodsDetailRequest goodsDetailRequest = new GoodsDetailRequest();
首先会根据GoodsDetailRequest的全限定名去查找GoodsDetailRequest.class对象。然后通过类加载器创建GoodsDetailRequest对象。
通常我们在获取Class对象时,可以通过Class.forName获取,也可以通过某个类的.class获取,也可以通过对象实例的getClass获取。
2、java.lang.reflect
java.lang.reflect
包的核心接口和类如下:
-
Member
接口:反映关于单个成员(字段或方法)或构造函数的标识信息。 -
Field
类:提供一个类的域的信息以及访问类的域的接口。 -
Method
类:提供一个类的方法的信息以及访问类的方法的接口。 -
Constructor
类:提供一个类的构造函数的信息以及访问类的构造函数的接口。 -
Array
类:该类提供动态地生成和访问 JAVA 数组的方法。 -
Modifier
类:提供了 static 方法和常量,对类和成员访问修饰符进行解码。 -
Proxy
类:提供动态地生成代理类和类实例的静态方法。
除了我们上面例子的基本使用,我们最常用的一个场景就是生曾动态代理。动态代理就是通过反射的机制来实现的。动态代理相关的知识,之前我也写过一篇文章: JAVA代理及Dubbo与Springboot的应用
参考资料:
微信分享/微信扫码阅读