用Core JAVA编程

可能重复:
什么是反思,为什么它有用?

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在解释反思方面做得很好。 反思似乎是爪哇的一只黑羊。 我总是听到有人说这是它的错误,而且容易出错,但是当它正确完成时,我发现它非常稳定和高效。 我会说避免使用它,并试图通过编写本机反射代码来建立一个自省库。 反思与反思相同,通常只是一个建立在底层反射库上的库。 如果你正在使用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);
        }
    }};
}
链接地址: http://www.djcxy.com/p/47613.html

上一篇: Programming with Core JAVA

下一篇: How does @autowired annotation works for a private field?