什么是java反射,为什么有用?
名称反射用于描述能够检查同一系统(或本身)中其他代码的代码。
例如,假设你在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#)中,这些概念非常相似。在动态类型的语言中,上述用例不是必需的(因为编译器将允许在任何对象上调用任何方法,如果不存在则在运行时失败),但是第二种情况是查找标记或以某种方式工作仍然很普遍。
我最喜欢的反射用法之一是下面的Java转储方法。它使用任何对象作为参数,并使用Java反射API打印出每个字段名称和值。
import java.lang.reflect.Array;
import java.lang.reflect.Field;
public static String dump(Object o, int callCount) {
callCount++;
StringBuffer tabs = new StringBuffer();
for (int k = 0; k < callCount; k++) {
tabs.append("\t");
}
StringBuffer buffer = new StringBuffer();
Class oClass = o.getClass();
if (oClass.isArray()) {
buffer.append("\n");
buffer.append(tabs.toString());
buffer.append("[");
for (int i = 0; i < Array.getLength(o); i++) {
if (i < 0)
buffer.append(",");
Object value = Array.get(o, i);
if (value.getClass().isPrimitive() ||
value.getClass() == java.lang.Long.class ||
value.getClass() == java.lang.String.class ||
value.getClass() == java.lang.Integer.class ||
value.getClass() == java.lang.Boolean.class
) {
buffer.append(value);
} else {
buffer.append(dump(value, callCount));
}
}
buffer.append(tabs.toString());
buffer.append("]\n");
} else {
buffer.append("\n");
buffer.append(tabs.toString());
buffer.append("{\n");
while (oClass != null) {
Field[] fields = oClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
buffer.append(tabs.toString());
fields[i].setAccessible(true);
buffer.append(fields[i].getName());
buffer.append("=");
try {
Object value = fields[i].get(o);
if (value != null) {
if (value.getClass().isPrimitive() ||
value.getClass() == java.lang.Long.class ||
value.getClass() == java.lang.String.class ||
value.getClass() == java.lang.Integer.class ||
value.getClass() == java.lang.Boolean.class
) {
buffer.append(value);
} else {
buffer.append(dump(value, callCount));
}
}
} catch (IllegalAccessException e) {
buffer.append(e.getMessage());
}
buffer.append("\n");
}
oClass = oClass.getSuperclass();
}
buffer.append(tabs.toString());
buffer.append("}\n");
}
return buffer.toString();
}
问题内容: 什么是反射,为什么有用? 我对Java特别感兴趣,但是我认为原理在任何语言中都是相同的。 问题答案: 名称反射用于描述能够检查同一系统(或本身)中的其他代码的代码。 例如,假设您在Java中有一个未知类型的对象,并且想在该对象上调用“ doSomething”方法(如果存在)。除非对象符合已知的接口,否则Java的静态类型化系统并不是真正为支持该类型而设计的,但是使用反射,您的代码可以
所谓反射,是java在运行时进行自我观察的能力,通过class、constructor、field、method四个方法获取一个类的各个组成部分。 在Java运行时环境中,对任意一个类,可以知道类有哪些属性和方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于反射机制。
本文向大家介绍什么是反射?相关面试题,主要包含被问及什么是反射?时的应答技巧和注意事项,需要的朋友参考一下 反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。
问题内容: 是因为我们应该加载类(例如),创建实例,然后搜索适当的方法,打包参数,然后仅调用方法?因此,大多数时间都花在了这些操作上,而不是花在对象上的显式方法调用上,对吧? 问题答案: 使用反射时,每次执行时都需要验证您执行的每个步骤。例如,当您调用一个方法时,它需要检查目标是否实际上是该方法的声明者的实例,是否具有正确数量的参数,每个参数是否具有正确的类型,等等。 绝对没有内联或其他性能技巧的
问题内容: 今天,我浏览了该站点上的一些问题,发现提到了 以单例模式使用的这种解决方案声称具有线程安全性的优点。 我从未使用过,并且使用Java编程已经有两年多了。显然,他们改变了很多。现在,他们甚至在自己内部提供了对OOP的全面支持。 现在为什么要在日常编程中使用枚举?为什么? 问题答案: 当变量(尤其是方法参数)只能从一小部分可能的值中取出一个时,应始终使用枚举。例如类型常量(合同状态:“永久
在Java9中有很多关于非法反射访问的问题。 我发现了很多关于如何处理错误消息的讨论,但我想知道非法反射访问实际上是什么。 所以我的问题是: 我认为这与Java9中引入的封装原则有关,但我找不到一个解释,说明它们是如何联系在一起的,是什么触发了警告,以及在什么场景中。