2012-10-04 63 views
0

我遇到了以下问题。通过反射在不同的包中调用公共方法

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

所以一个simplifed代码如下所示:

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文档中遗漏了一些东西,或者这是不可能的,尽管只是简单地调用已实现的方法是可能的,而没有反射。

回答

1

我发现了。我需要在实现的接口上调用getDeclaredMethod,而不是在类上。

例子:

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

由于类有一个包可见其方法的公开程度实际上是在封装级,而不是公共像你想象的。 所以,你有方法调用之前调用method.setAccessible(true)

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

这也有用,谢谢。我想我错过了'Reflection'实现中的一些东西。 –

+0

实际上该方法的可见性仍然是公开的,我可以在上面的示例中将其称为没有问题,即使错误也是如此。但有一个检查由于课堂可见性而拒绝调用方法。 –

0

查看文档setAccessible。虽然SecurityPolicy可能会阻止您使其可访问。

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

+0

不幸的是我需要担心可见性,因为我尝试通过Jetty的'XmlConfiguration'创建对象。 –

相关问题