2017-03-21 61 views
1

調用此代碼:雖然java.lang.NoSuchMethodError拋出的直接調用,該方法可以通過反射

Boolean isSecure = configInstance.isSecure(); 

失敗,此錯誤:

java.lang.NoSuchMethodError: org.Config.isSecure()Z 

,但是,我可以調用在調試模式下通過反射也是一樣的。

org.Config.class.getMethod("isSecure").invoke(configInstance); 

這是方法簽名:

public Boolean isSecure(); 

一些背景:這是一個bean類的一部分。此前,此方法返回布爾基元類型。但是,我想捕獲未設置bean字段值的場景。我在這裏做錯了什麼?編號1:

下面是一個示例代碼。我在使用JDK 1.8.0_60的Mac上。

try { 
    isSecure = (Boolean) configInstance.getClass().getMethod("isSecure").invoke(configInstance); 
    log.info("isSecure " + isSecure);  // prints true 
    isSecure = configInstance.isSecure(); // error NoSuchMethodError 
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { 
    log.error(e.getMessage(), e); 
} 
+0

'布爾isSecure = configInstance.isSecure();' 編譯沒有任何錯誤? – Uata

+0

聽起來像某些東西沒有編譯,沒有足夠的信息來診斷這一點。 – john16384

+0

當然它是編譯好的。 –

回答

0

的方法,從boolean xyz()改變爲Boolean xyz(),但沒有重新編譯到一個新的JAR。這些方法的簽名略有不同。第一個是:

xyz()Z 

另一種是:

xyz()Ljava.lang.Boolean; 

但是,當您使用反射,你正在尋找一個叫做xyz不帶參數的方法。在這兩種情況下都存在這種方法。

但是,調用invoke時,有一個細微的差別:

Boolean b = (Boolean) SomeClass.class.getMethod("xyz").invoke(instance); 

不同的是,在第一種情況下,自動裝箱從發生到booleanBoolean。在第二種情況下,不需要自動裝箱。

這就是爲什麼反射版本適用於兩個版本。

爲什麼你DONOT得到正常呼叫編譯錯誤,喜歡它的原因:

Boolean b = xyz(); 

...可能是因爲你在你的IDE加載這兩個項目。 IDE將使用本地更改的版本並正確編譯它。

相關問題