繁体   English   中英

通过反射在不同包中的类上调用公共方法

[英]Invoking public method on a class in a different package via reflection

我遇到了以下问题。

我在包a有两个不同的包,我想在包b调用接口的实现方法,但是实现类具有包可见性。

因此,简化的代码如下所示:

package b;

public final class Factory {
    public static B createB() {
        return new ImplB();
    }

    public interface B {
        void method();
    }

    static class ImplB implements B {
        public void method() {
            System.out.println("Called");
        }
    }
}

和调用者:

package a;

import java.lang.reflect.Method;
import b.Factory;
import b.Factory.B;

public final class Invoker {
    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[] {};
    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[] {};

    public static void main(String... args) throws Exception {
        final B b = Factory.createB();
        b.method();

        final Method method = b.getClass().getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
        method.invoke(b, EMPTY_OBJECT_ARRAY);
    }
}

当我启动程序时,它会按预期打印出Called并抛出异常,因为程序包的可见性禁止调用发现的方法。

所以我的问题是解决这个问题的任何方法吗? 我是否在Java文档中缺少某些内容,或者根本不可能做到这一点,尽管仅需调用一个实现的方法就可以了,而无需反思。

由于类具有程序包可见性,因此其方法的可见性实际上是程序包级别,而不是您认为的公共级别。 因此,您必须在方法调用之前调用method.setAccessible(true)

 final Method method = b.getClass().getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
 method.setAccessible(true);
 method.invoke(b, EMPTY_OBJECT_ARRAY);

我知道了 我需要在实现的接口上而不是在类上调用getDeclaredMethod

例:

final Method method = B.class.getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
method.invoke(b, EMPTY_OBJECT_ARRAY);

请参阅文档setAccessible 但是,SecurityPolicy可能会阻止您对其进行访问。

但是尚不清楚您是否需要反思。 多态性的好处之一是客户端可以调用B.method()而无需访问(甚至担心)实现接口的具体类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM