Java学习Day25:基础篇15:反射
Java 反射(Reflection)
1.前置反应
是 Java 编程语言的一个强大特性,它允许程序在运行时检查或修改类的行为。这包括获取类的信息(如字段、方法、构造函数等),以及动态地创建对象、调用方法、访问和修改字段等。
下面将介绍 Java 反射的主要知识点,并给出相应的代码示例。
1. 获取 Class 对象
- 通过对象实例:
Class<?> clazz = obj.getClass();
- 通过类字面量:
Class<?> clazz = MyClass.class;
- 通过 Class.forName():
Class<?> clazz = Class.forName("com.example.MyClass");
2. 访问字段
- 获取字段:
Field field = clazz.getDeclaredField("fieldName");
- 设置访问权限:
field.setAccessible(true);
- 获取和设置字段值:
field.get(obj);
和field.set(obj, value);
3. 访问方法
- 获取方法:
Method method = clazz.getDeclaredMethod("methodName", parameterTypes);
- 设置访问权限:
method.setAccessible(true);
- 调用方法:
method.invoke(obj, args);
4. 访问构造函数
- 获取构造函数:
Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);
- 设置访问权限:
constructor.setAccessible(true);
- 创建对象:
Object instance = constructor.newInstance(args);
注意事项
- 反射会绕过 Java 编译器的类型检查,因此使用反射时要特别小心,以避免运行时错误。
- 反射操作通常比直接代码调用要慢,因为它涉及到类型检查、安全检查等额外步骤。
- 过度使用反射可能会使代码难以理解和维护。
2.小案例:
package rel; import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; public class reflection { public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { Properties properties=new Properties(); FileInputStream fileInputStream=new FileInputStream("D:\\a\\rel.txt"); properties.load(fileInputStream); String className =properties.get("className").toString(); String methodName=properties.get("methodName").toString(); String age = properties.get("age").toString(); Class classperson = Class.forName(className); //返回Person类的运行时对象classperson,也是一个类 Constructor con =classperson.getConstructor(int.class,String.class); //调用构造方法,用来生成之后要用的person实例 Object personn=con.newInstance(22,"Tom"); System.out.println(classperson); Method method =classperson.getDeclaredMethod(methodName,null); //创建method5的运行时方法实例 method.setAccessible(true); System.out.println(method); method.invoke(personn); //以前是person.方法,现在是方法invoke(实例) } }
3.反射机制
1.在代码编译阶段,字节码文件在JVM中是通过类加载器被加载到方法区中。
2.方法区存储了类的结构信息、常量、静态变量以及编译后的代码等数据,为JVM执行Java程序提供了必要的支持。
3.当类被加载到JVM中时,其结构信息(如方法定义和常量)主要存储在方法区中,而类的实例(对象)则在堆上分配。栈用于存储与类实例相关的方法调用和局部变量。这些区域共同协作,以支持Java程序的运行。
4.反射优缺点
反射调用优化提速,关闭访问检测:
5.class类
不同阶段获取class对象的方式;
javac生成字节码文件后通过类加载器把字节码加载到内存中生成class对象,并在方法区中得到了类的字节码的二进制数据。
1.通常用于使用全路径对配置文件进行读取,框架多用
2.3.4.
6.哪些类型有class对象
7.类加载
普通的类是new出来静态加载,有错直接报,使用反射加载类是动态加载,只有运行到时才报错
Important图
加载(前两个阶段jvm控制)
链接:
验证
对文件安全性包括但不限于文件描述符,字节码文件等进行校验
准备
对静态变量进行默认初始化,并分配空间
0,null之类
解析
将符号引用转换为直接引用
初始化(最后一个阶段,程序员控制)
加载类时有同步锁,保证某个类在内存中只有一份class对象。