可能重复:
什么是反射,它为什么有用?
Java中反射的确切用途是什么?有人可以举个例子吗?如果有任何相关的概念,请分享。
反射是一种强大的构造,经常被 Guice 和 Hibernate 等底层库用来简化生活。它通常用于需要配置类然后动态实例化的地方。例如:
public Strategy prepare(String clazz, Properties config) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> clazz = Class.forName(clazz);
Strategy strategy = (Strategy) clazz.newInstance();
strategy.initialise(config);
return strategy;
}
在这里,clazz 参数命名要实例化的类。假定该类将是 Strategy 类/接口的子类。然后也使用通过 config 参数传入的设置来启动它。这允许高度可配置/动态的环境。
然而,反射经常会导致非常危险(和恶意)的代码,因此,除非绝对必要,否则应该避免反射。还要记住,反射比直接调用要慢。这是一个从生产系统中提取的如何不使用反射的实际示例。
private static CacheManager getRawInstance() {
lock.lock();
try {
final Field field = CacheManager.class.getDeclaredField("singleton");
field.setAccessible(true); // << -- ??
return (CacheManager) field.get(CacheManager.class);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
} finally {
lock.unlock();
}
}
在这里,ehcache 中的私有字段被更改和访问。这是彻头彻尾的糟糕编码。
TechExchange 在解释反射方面做得很好。反射似乎是 Java 中的害群之马。我总是听到人们说这是它的错误和容易出错,但我发现它在正确完成时非常稳定和高效。我会说避免使用它并尝试使用内省库而不是编写本机反射代码。自省和反射一样,一般只是建立在底层反射库上的库。如果您正在使用 bean,那么 Spring 和 Apache-commons 都有很好的工具。
Spring 和 Apache 只针对 getter,不幸的是,我并不生活在 bean 世界中。我必须使用的一些对象是布尔“is”方法,并且确实发现自己正在编写反射代码。
无论如何,这里有一些简单的反射代码,它用 0 个参数存储每个公共方法。
public void foo(final Class _class){
List<Method> methods = new ArrayList<Method>(){{
for( Method method : _class.getMethods() ) {
if( Modifier.isPublic( method.getModifiers() )
&& method.getGenericParameterTypes().length == 0 ){
add(method);
}
}};
}