2012-10-04 66 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'創建對象。 –

相關問題