我遇到了以下问题。
我在包a
中有两个不同的包,我想调用包b
中接口(interface)的实现方法,但实现类具有包可见性。
简化的代码如下所示:
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);
关于java - 通过反射调用不同包中的类的公共(public)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12730721/