什么是反射,为什么它有用?

2022-08-31 01:23:51

什么是反射,为什么它有用?

我对 特别感兴趣,但我认为这些原则在任何语言中都是相同的。Java


答案 1

名称反射用于描述能够检查同一系统(或自身)中的其他代码的代码。

例如,假设您在Java中有一个未知类型的对象,并且您希望在其上调用“doSomething”方法(如果存在)。Java的静态类型系统并不是真正为支持它而设计的,除非对象符合已知的接口,但是使用反射,你的代码可以查看对象并找出它是否有一个名为“doSomething”的方法,然后根据需要调用它。

所以,给你一个Java中的代码示例(想象一下有问题的对象是foo):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

Java中一个非常常见的用例是使用注释。例如,JUnit 4 将使用反射来查看类中标记有@Test注释的方法,然后在运行单元测试时调用它们。

有一些很好的反思示例可以帮助您开始 http://docs.oracle.com/javase/tutorial/reflect/index.html

最后,是的,这些概念在其他支持反射的静态类型语言中非常相似(如C#)。在动态类型语言中,上面描述的用例不太必要(因为编译器将允许在任何对象上调用任何方法,如果它不存在,则在运行时失败),但是寻找以某种方式标记或工作的方法的第二种情况仍然很常见。

从评论更新:

检查系统中的代码并查看对象类型的能力不是反射,而是类型内省。然后,反射是通过利用内省在运行时进行修改的能力。这种区别在这里是必要的,因为某些语言支持内省,但不支持反射。一个这样的例子是C++


答案 2

反射是语言在运行时检查和动态调用类、方法、属性等的能力。

例如,Java中的所有对象都有方法,即使您在编译时不知道该对象的类(例如,如果您将其声明为),也可以确定该对象的类 - 这可能看起来微不足道,但是在动态性较低的语言中是不可能的,例如.更高级的用法允许您列出和调用方法,构造函数等。getClass()ObjectC++

反射很重要,因为它允许您编写不必在编译时“知道”所有内容的程序,从而使它们更具动态性,因为它们可以在运行时绑定在一起。代码可以针对已知接口编写,但要使用的实际类可以使用配置文件中的反射进行实例化。

出于这个原因,许多现代框架广泛使用反射。大多数其他现代语言也使用反射,并且在脚本语言(如Python)中,它们甚至更紧密地集成在一起,因为在这些语言的一般编程模型中感觉更自然。