什么是反思,为什么它有用?
我对Java特别感兴趣,但我认为任何语言的原理都是一样的。
什么是反思,为什么它有用?
我对Java特别感兴趣,但我认为任何语言的原理都是一样的。
当前回答
反射允许在运行时动态实例化新对象、调用方法和获取/设置类变量的操作,而无需事先了解其实现。
Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();
//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class);
Object returnValue = method.invoke(null, "parameter-value1");
在上面的示例中,null参数是要对其调用方法的对象。如果方法是静态的,则提供null。如果该方法不是静态的,那么在调用时需要提供有效的MyObject实例而不是null。
反射还允许您访问类的私有成员/方法:
public class A{
private String str= null;
public A(String str) {
this.str= str;
}
}
.
A obj= new A("Some value");
Field privateStringField = A.class.getDeclaredField("privateString");
//Turn off access check for this field
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
为了检查类(也称为内省),不需要导入反射包(java.lang.reflect)。可以通过java.lang.Class访问类元数据。
反射是一个非常强大的API,但如果过度使用,它可能会降低应用程序的速度,因为它在运行时解析所有类型。
其他回答
正如名称本身所暗示的,它除了提供在运行时动态调用创建实例的方法的功能之外,还反映了它所持有的例如类方法等。
许多框架和应用程序都使用它来调用服务,而实际上并不知道代码。
我觉得最好用例子来解释,但没有一个答案能做到这一点。。。
使用反射的一个实际例子是用Java编写的Java语言服务器或用PHP编写的PHP语言服务器等。语言服务器为您的IDE提供自动完成、跳转到定义、上下文帮助、提示类型等功能。为了让所有标记名(可以自动完成的单词)在键入时显示所有可能的匹配项,语言服务器必须检查类的所有内容,包括文档块和私有成员。为此,它需要对所述阶级的反思。
另一个例子是私有方法的单元测试。这样做的一种方法是创建一个反射,并在测试的设置阶段将方法的范围更改为公开。当然,有人会认为不应该直接测试私有方法,但这不是重点。
反射是让物体看到它们的外观。这个论点似乎与反思无关。事实上,这就是“自我识别”能力。
反射本身是指Java和C#等缺乏自我认知和自我感知能力的语言。因为他们没有自知之明的能力,当我们想要观察它的样子时,我们必须有另一件事来反思它的样子。优秀的动态语言,如Ruby和Python,可以在没有其他人帮助的情况下感知自己的反射。我们可以说,Java的对象在没有镜像的情况下无法感知它的样子,镜像是反射类的对象,但Python中的对象可以在没有镜像时感知它。这就是为什么我们需要在Java中进行反射。
反射使您能够编写更通用的代码。它允许您在运行时创建对象并在运行时调用其方法。因此,程序可以高度参数化。它还允许对对象和类进行内省,以检测其暴露于外部世界的变量和方法。
根据我的理解:
反射允许程序员动态访问程序中的实体。也就是说,当程序员对应用程序进行编码时,如果不知道类或其方法,他可以通过使用反射来动态地(在运行时)使用此类类。
它经常用于类名频繁更改的场景。如果出现这种情况,那么程序员重写应用程序并一次又一次地更改类的名称是很复杂的。
相反,通过使用反射,需要担心类名可能会发生变化。