建设网站后台,好看网站手机版,国内正规的现货交易平台,青海最好的网站建设公司什么是反射#xff1f;
Java的反射是指在程序运行时#xff0c;对于任意一个类#xff0c;都可以获取到这个类的所有属性和方法#xff0c;并能够对其进行操作。通过反射机制#xff0c;可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松…什么是反射
Java的反射是指在程序运行时对于任意一个类都可以获取到这个类的所有属性和方法并能够对其进行操作。通过反射机制可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松地实现一些复杂的功能但也会带来一些性能上的损失。
Java反射机制的基本步骤
获取Class对象通过反射可以动态地获取类对象即Class对象。Class对象是Java运行时系统中的一个重要概念每个类都有一个与之对应的Class对象通过Class对象可以获取类的所有信息。
示例代码
Class clazz Class.forName(java.lang.String); // 获取String类的Class对象创建对象通过Class对象可以实例化一个具体的对象。
示例代码
Object obj clazz.newInstance(); // 实例化一个String对象访问属性通过反射可以获取和设置对象的属性包括公共的和私有的。
示例代码
Field field clazz.getField(value); // 获取value属性
Object value field.get(strObj); // 获取value属性的值
field.set(strObj, newValue); // 设置value属性的值为newValue调用方法通过反射可以调用对象的方法包括公共的和私有的。
示例代码
Method method clazz.getMethod(substring, int.class, int.class); // 获取substring方法
Object result method.invoke(strObj, startIndex, endIndex); // 调用substring方法传递参数startIndex和endIndex执行构造函数通过反射可以调用对象的构造函数来实例化对象。
示例代码
Constructor constructor clazz.getConstructor(String.class); // 获取含有一个String类型参数的构造函数
Object obj constructor.newInstance(Hello, World!); // 调用构造函数并实例化对象Java的反射机制带来了很多便利但同时也会损失一些性能在使用时需要慎重考虑其是否真正必要。
反射的应用场景了解么
像咱们平时大部分时候都是在写业务代码很少会接触到直接使用反射机制的场景。但是这并不代表反射没有用。相反正是因为反射你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。
这些框架中也大量使用了动态代理而动态代理的实现也依赖反射。
比如下面是通过 JDK 实现动态代理的示例代码其中就使用了反射类 Method 来调用指定的方法。
public class DebugInvocationHandler implements InvocationHandler {/*** 代理类中的真实对象*/private final Object target;public DebugInvocationHandler(Object target) {this.target target;}public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {System.out.println(before method method.getName());Object result method.invoke(target, args);System.out.println(after method method.getName());return result;}
}另外像 Java 中的一大利器 注解 的实现也用到了反射。为什么你使用 Spring 的时候 一个Component注解就声明了一个类为 Spring Bean 呢为什么你通过一个 Value注解就读取到配置文件中的值呢究竟是怎么起作用的呢这些都是因为你可以基于反射分析类然后获取到类/属性/方法/方法的参数上的注解。你获取到注解之后就可以做进一步的处理。
反射在Java中是一种高级的语言特性它允许程序在运行时动态地获取类的信息、访问和操作类的属性和方法等。因此它的应用场景非常广泛以下是一些例子 框架开发许多框架如Spring利用反射获取类的信息和属性来实现依赖注入、控制反转等功能。 动态代理利用反射机制来动态生成代码从而实现对某些对象的代理。 注解解析通过反射来获取类、方法、字段等的注解信息。 Java序列化反射机制使得可以在编译时未知的情况下将对象序列化为字节流然后再通过反射将字节流转换成对象。 反编译工具反编译工具利用反射实现对Java代码的分析和探测可以查看方法、字段的信息以及代码的执行流程等。
总之反射机制是Java语言中非常有用的一种特性能够极大地提高程序的可扩展性、灵活性和可维护性。
反射机制的优缺点有哪些
优点
动态性能够运行时动态获取类的信息访问和操作类的属性和方法提高了灵活性例如可与动态编译结合 Class.forName(‘com.mysql.jdbc.Driver.class’)加载MySQL的驱动类;适应性反射机制不依赖于具体的硬件、操作系统和JVM可以应用于任何Java程序中;灵活性反射机制提供了更灵活的编程方式可以在不知道具体的类名的情况下创建对象、调用方法等。
缺点
性能问题使用反射性能较低需要解析字节码将内存中的对象进行解析。其解决方案是通过 setAccessible(true) 关闭JDK的安全检查来提升反射速度安全问题反射机制可以访问和修改对象的私有属性和方法有可能会破坏程序的安全性和稳定性因此必须谨慎使用可读性问题反射机制动态调用方法和属性代码可读性较差不容易维护和调试。
总之优点就是动态获取类信息操作类的属性和方法们这是核心缺点无非就是性能、安全和可读性一定不要死记硬背要通过原理去理解。
如何获取反射中的Class对象
Class.forName(“类的路径”)当你知道该类的全路径名时你可以使用该方法获取 Class 类对象。
Class clz Class.forName(java.lang.String);类名.class。这种方法只适合在编译前就知道操作的 Class。
Class clz String.class;对象名.getClass()。
String str new String(Hello);
Class clz str.getClass();如果是基本类型的包装类可以调用包装类的Type属性来获得该包装类的Class对象。
除了上述几种种方法还可以通过ClassLoader类的loadClass()方法来获取Class对象这种方式常用于加载外部或动态生成的类。
Java反射API有几类
反射 API 用来生成 JVM 中的类、接口或则对象的信息。 Class 类反射的核心类可以获取类的属性方法等信息。 Field 类Java.lang.reflect 包中的类表示类的成员变量可以用来获取和设置类之中的属性值。 Method 类Java.lang.reflect 包中的类表示类的方法它可以用来获取类中的方法信息或者执行方法。 Constructor 类Java.lang.reflect 包中的类表示类的构造方法。
反射使用的步骤 获取想要操作的类的Class对象这是反射的核心通过Class对象我们可以任意调用类的方法。 调用 Class 类中的方法既就是反射的使用阶段。 使用反射 API 来操作这些信息。
具体可以看下面的例子
public class Student {private Integer age;public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public static void main(String[] args) {//正常调用Student student new Student();student.setAge(16);System.out.println(Student Age : student.getAge());//使用反射调用try {Class? aClass Class.forName(com.lzl.javaSE.test8.Student);Method setAge aClass.getMethod(setAge, Integer.class);Constructor? studentConstructor aClass.getConstructor();Object studentObject studentConstructor.newInstance();setAge.invoke(studentObject, 18);Method getAge aClass.getMethod(getAge);System.out.println(Student Age : getAge.invoke(studentObject));} catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException |IllegalAccessException e) {throw new RuntimeException(e);}}
}从代码中可以看到我们使用反射调用了 setAge方法并传递了 16 的值。之后使用反射调用了 getAge 方法输出其年龄。上面的代码整个的输出结果是
Student Age : 16
Student Age : 18从这个简单的例子可以看出一般情况下我们使用反射获取一个对象的步骤
获取类的 Class 对象实例
Class? aClass Class.forName(com.lzl.javaSE.test8.Student);根据 Class 对象实例获取 Constructor 对象
Constructor? studentConstructor aClass.getConstructor();使用 Constructor 对象的 newInstance 方法获取反射类对象
Object studentObject studentConstructor.newInstance();而如果要调用某一个方法则需要经过下面的步骤
获取方法的 Method 对象
Method setAge aClass.getMethod(setAge, Integer.class);利用 invoke 方法调用方法
setAge.invoke(studentObject, 18);使用反射拿到私有属性值
Java通过反射机制可以获取和操作类、方法、字段等信息。在Java中私有属性对外不可见因此不能直接访问私有属性的值。但是我们可以使用反射机制来绕过访问限制获取私有属性的值。
下面是获取私有属性值的示例代码
import java.lang.reflect.Field;public class PrivateFieldTest {private String privateField private value;public static void main(String[] args) throws Exception {PrivateFieldTest obj new PrivateFieldTest();// 获取私有属性对象Field field PrivateFieldTest.class.getDeclaredField(privateField);// 设置可访问私有属性field.setAccessible(true);// 获取私有属性值String value (String) field.get(obj);// 输出私有属性值System.out.println(privateField value: value);}
}在上面的示例代码中我们首先定义了一个私有属性privateField然后在main方法中通过反射机制获取privateField的值。这里要注意我们要通过类的getDeclaredField方法获取私有属性对象并且要将其设置为可访问状态。
另外我们还需要调用Field类的get方法获取私有属性的值其中第一个参数是对象实例表示要获取该对象中的私有属性值。最后我们将获取到的私有属性值输出。