什么是反思,为什么它有用?
我对Java特别感兴趣,但我认为任何语言的原理都是一样的。
什么是反思,为什么它有用?
我对Java特别感兴趣,但我认为任何语言的原理都是一样的。
当前回答
根据我的理解:
反射允许程序员动态访问程序中的实体。也就是说,当程序员对应用程序进行编码时,如果不知道类或其方法,他可以通过使用反射来动态地(在运行时)使用此类类。
它经常用于类名频繁更改的场景。如果出现这种情况,那么程序员重写应用程序并一次又一次地更改类的名称是很复杂的。
相反,通过使用反射,需要担心类名可能会发生变化。
其他回答
反射是一种语言在运行时检查和动态调用类、方法、属性等的能力。
例如,Java中的所有对象都有getClass()方法,该方法允许您确定对象的类,即使您在编译时不知道它(例如,如果您将其声明为object)-这可能看起来微不足道,但这种反射在动态性较差的语言(如C++)中是不可能的。更高级的用法允许您列出和调用方法、构造函数等。
反射是很重要的,因为它让你编写的程序不必在编译时“知道”一切,使它们更加动态,因为它们可以在运行时绑定在一起。代码可以针对已知的接口编写,但要使用的实际类可以使用配置文件的反射来实例化。
出于这个原因,许多现代框架广泛使用反射。大多数其他现代语言也使用反射,在脚本语言(如Python)中,它们甚至更紧密地集成在一起,因为在这些语言的通用编程模型中感觉更自然。
反射是一种API,用于在运行时检查或修改方法、类和接口的行为。
反射所需的类在java.lang.reflect包中提供。反射为我们提供了有关对象所属的类的信息,以及可以使用该对象执行的该类的方法。通过反射,我们可以在运行时调用方法,而不考虑与它们一起使用的访问说明符。
java.lang和java.lang.reflect包为java反射提供了类。
反射可用于获取以下信息:
类getClass()方法用于获取对象所属类的名称。构造函数getConstructors()方法用于获取对象所属类的公共构造函数。方法getMethods()方法用于获取对象所属类的公共方法。
反射API主要用于:
IDE(集成开发环境),例如Eclipse、MyEclipse、NetBeans等。调试器和测试工具等。
使用反射的优点:
可扩展性特性:应用程序可以通过使用扩展性对象的完全限定名称创建扩展性对象实例来使用外部用户定义的类。
调试和测试工具:调试器使用反射属性来检查类上的私有成员。
缺点:
性能开销:反射操作的性能低于非反射操作,应避免在性能敏感应用程序中频繁调用的代码段中使用。
内部暴露:反射代码打破了抽象,因此可能会随着平台的升级而改变行为。
参考:Java Reflection javareviewed.blogspot.in
名称反射用于描述能够检查同一系统(或其本身)中其他代码的代码。
例如,假设您在Java中有一个未知类型的对象,如果存在,您希望对其调用“doSomething”方法。Java的静态类型系统并不是为了支持这一点而设计的,除非对象符合已知的接口,但是使用反射,您的代码可以查看对象并找出它是否有一个名为“doSomething”的方法,如果需要,可以调用它。
因此,给您一个Java代码示例(假设所讨论的对象是foo):
Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);
Java中一个非常常见的用例是注释的用法。例如,JUnit4将使用反射在类中查找标记有@Test注释的方法,然后在运行单元测试时调用它们。
有一些很好的反思示例可以帮助您开始http://docs.oracle.com/javase/tutorial/reflect/index.html
最后,是的,这些概念在其他支持反射的静态类型语言(如C#)中非常相似。在动态类型语言中,上面描述的用例不太必要(因为编译器将允许在任何对象上调用任何方法,如果不存在,则在运行时失败),但是第二种情况仍然很常见,即查找被标记或以某种方式工作的方法。
从评论更新:
检查系统中的代码并查看对象类型的能力是不是反思,而是类型反思。反射就是能够在运行时通过使用反省在某些语言中,这种区别是必要的支持内省,但不支持反思。一个这样的例子是C++
反射是让物体看到它们的外观。这个论点似乎与反思无关。事实上,这就是“自我识别”能力。
反射本身是指Java和C#等缺乏自我认知和自我感知能力的语言。因为他们没有自知之明的能力,当我们想要观察它的样子时,我们必须有另一件事来反思它的样子。优秀的动态语言,如Ruby和Python,可以在没有其他人帮助的情况下感知自己的反射。我们可以说,Java的对象在没有镜像的情况下无法感知它的样子,镜像是反射类的对象,但Python中的对象可以在没有镜像时感知它。这就是为什么我们需要在Java中进行反射。
反射的简单示例。在国际象棋游戏中,您不知道用户在运行时会移动什么。反射可用于调用已在运行时实现的方法:
public class Test {
public void firstMoveChoice(){
System.out.println("First Move");
}
public void secondMOveChoice(){
System.out.println("Second Move");
}
public void thirdMoveChoice(){
System.out.println("Third Move");
}
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Test test = new Test();
Method[] method = test.getClass().getMethods();
//firstMoveChoice
method[0].invoke(test, null);
//secondMoveChoice
method[1].invoke(test, null);
//thirdMoveChoice
method[2].invoke(test, null);
}
}