2012-08-12 65 views
6

所以,我有一個奇怪的問題。 這個表達式:method.invoke(target, null)拋出java.lang.IllegalArgumentException異常:錯誤的參數數目可變參數和空參數

的問題是,這是表達內心深處的休眠(BasicPropertyAccessor $ BasicGetter要準確),我想它應該工作正常(它確實直到最近)

我在eclipse中調試這個問題,事實上,如果我(在顯示視圖中)調用method.invoke(target)method.invoke(target, (Object[]) null)一切工作正常。 我確定我的班有這個getter,它沒有參數。所以......問題是,到底發生了什麼?!

編輯:

  • 方法是java.lang.reflect.Method中和點的對所述吸氣
  • 目標的實例是類的公共X的getX()吸氣劑
  • 一個實例JDK 1.6.0_31
  • 在休眠代碼(BasicPropertyAccessor:143):

    public Object get(Object target) throws HibernateException { 
        try { 
         return method.invoke(target, null); 
        } 
        catch{ ... } 
    } 
    
+0

你試圖調用什麼方法? – Jeffrey 2012-08-12 01:46:21

+0

session.flush():P但最後,hibernate試圖調用getter – mabn 2012-08-12 01:47:31

+0

該方法的簽名是什麼? – Bohemian 2012-08-12 01:57:33

回答

8

當傳遞null值到一個可變參數的方法,它可以解釋爲兩件事情之一:

  • null陣列
  • 與作爲null一種元素的數組。

Java選擇前者,除非將null顯式轉換爲可變參數方法的組件類型。 (爲了清晰起見,建議您明確地使用任何一種方法,否則在Eclipse中也會得到一個令人厭惡的警告。)

當調用不帶參數的方法時,可以傳入Method.invoke數組0元素,沒有額外的參數(這將導致在一個空數組),或一個null數組:

public class MethodInvoke { 
    public static void noParams() { 
     System.out.println("noParams called"); 
    } 

    public static void main(String[] args) throws NoSuchMethodException, 
      SecurityException, IllegalAccessException, 
      IllegalArgumentException, InvocationTargetException { 
     Method noParams = MethodInvoke.class.getMethod("noParams"); 
     Object target = null; 
     noParams.invoke(target, new Object[0]); 
     noParams.invoke(target); 
     noParams.invoke(target, null); 
     noParams.invoke(target, (Object[]) null); 
     noParams.invoke(target, (Object) null); // wrong number of arguments 
    } 
} 

似乎是發生的是,method.invoke(target, null)被解釋爲method.invoke(target, (Object) null)。這與Java應該如何表現不一致。

你確定你的方法沒有參數嗎?

我還注意到,在較新版本的hibernate中,他們明確地將null轉換爲Object[]

+0

好吧,我清除了Maven存儲庫,重新創建數據庫,工作區,.project和.classpath文件,並開始工作。我仍然不知道它爲什麼如此奇怪。 – mabn 2012-08-13 19:21:10

+0

@mabn是的,這是一個非常奇怪的錯誤。至少如果它再次咬你,你會知道該怎麼辦 – Jeffrey 2012-08-13 21:20:01

0

如果該方法的簽名是public X getX(),則有沒有參數,所以這樣稱呼它:

method.invoke(target); 

invoke()方法的第一個參數是,在其上調用方法的實例。

請注意,對於可變參數方法,使用逗號(例如method(a, b, c))指定參數的方式是method(new Object[]{a, b, c}的語法糖:形式參數類型爲Object[]

+0

這應該不重要。看我的回答 – Jeffrey 2012-08-12 02:24:31

+0

我不能改變你提供的表達式,hibernate調用它。 – mabn 2012-08-12 02:28:25