当前位置: 首页 > 后端技术 > Java

Java中的反射机制

时间:2023-04-01 17:47:02 Java

reflection是什么?反射:指在运行时通过反射API获取类的内部信息,可以直接操作任何对象的属性和方法。当一个类被加载时,这个类的信息存放在Java虚拟机的方法区,这个类的对象实例存放在虚拟机的堆中。通过方法区获取和操作一个类,就像是通过一面镜子反射堆上的对象。JDK提供了java.lang.Class类来支持反射机制。java.lang.Class类的理解就是Java中的一切都是对象,我们创建的类本身就是一个对象。Java程序通过javac命令编译生成一个或多个字节码文件(.class),一个字节码文件对应一个唯一的类或接口的定义信息;然后用java命令解释一个字节码文件运行(类加载)相当于把这个字节码文件加载到内存中,我们称之为运行时类,而这个运行时类其实就是一个java.lang.Class对象。也就是说,一个Class实例对应一个运行时类。加载到内存中的运行时类会被缓存一段时间。在这段时间里,我们可以通过不同的方法获取运行时类,那么如何获取运行时类,即Class实例呢?获取Class实例的方法//方法一:调用运行时类的.class属性Classclazz1=Student.class;//Student是我们自定义的类//方法二:调用运行时类的getClass方法Students=newStudent();Classclazz2=p1.getClass();//方法三:调用Class类的静态方法:forName(StringclassPath)Classclazz3=Class.forName("com.example.java.Student");//这个方法用的比较多。哪些数据类型可以获得Class实例?对象、接口、数组、枚举类、注解、基本数据类型、void类型、Class本身。通过反射操作创建运行时类的对象://通过newInstance()方法(运行时类必须有一个可见的空参数构造函数)Classclazz=Student.class;Students=clazz.newInstance();//类使用了泛型,所以newInstance()不需要强制类型获取运行时类的属性(Fields):Classclazz=Student.class;//getFields():获取当前运行时类及其父类在类中声明为public的属性??Field[]fields=clazz.getFields();//getDeclaredFields():获取当前运行时类的所有属性(不包括的属性父类)Field[]declaredFields=clazz.getDeclaredFields();获取运行时类(Methods)的方法:Classclazz=Student.class;Method[]methods=clazz.getMethods();Method[]declaredMethods=clazz.getDeclaredMethods();什么时候使用反射?反射提供了一种动态性,即在运行时获取类信息,创建类对象,并操作相应的方法。比如一个网站的前后端,后端服务器是运行着的,此时前端用户发送登录请求,然后后端创建相应的对象完成登录——相关操作,因为此时后台已经在运行,所以不能通过new来创建对象,通过反射机制来创建。比如我们在Spring中配置bean:当我们在XML中配置bean时,Spring会在启动时使用反射机制创建对应的对象。反射和封装是矛盾的吗?并不矛盾,当将一个类的某些方法设置为私有权限时,就意味着告诉其他类不要调用这些方法,使用其他方法即可满足要求,体现封装性;而反射只是提供了一种机制,让我们可以访问类的私有方法,但原则上不建议调用这些私有方法。参考资料:上硅谷Java入门大白话讲Java反射:介绍、使用、原理