簡體   English   中英

使用反射調用PumpEvents時java.lang.illegalArgumentException

[英]java.lang.illegalArgumentException when calling pumpEvents using reflection

我試圖在Java Applet中制作模態框架,如下所示: http : //www.java2s.com/Tutorial/Java/0240__Swing/Showthegivenframeasmodaltothespecifiedowner.htm 這段代碼具有start()函數,看起來像

public void start() throws Exception {
  Class<?> clazz = Class.forName("java.awt.Conditional");
  Object conditional = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz },
      this);
  Method pumpMethod = Class.forName("java.awt.EventDispatchThread").getDeclaredMethod(
      "pumpEvents", new Class[] { clazz });
  pumpMethod.setAccessible(true);
  pumpMethod.invoke(Thread.currentThread(), new Object[] { conditional });
}.

當我打電話

 pumpMethod.invoke(Thread.currentThread(), new Object[] { conditional });

我有以下例外:

    java.lang.RuntimeException: java.lang.IllegalArgumentException: object is not an instance of declaring class
    at wizard.ModalFrameUtil.showAsModal(ModalFrameUtil.java:136)
    at wizard.WizardCore.showWizardFrame(WizardCore.java:206)
    at SelfRegistrationApplet$1.run(SelfRegistrationApplet.java:55)
    at SelfRegistrationApplet$1.run(SelfRegistrationApplet.java:35)
    at java.security.AccessController.doPrivileged(Native Method)
    at SelfRegistrationApplet.RunSelfRegistrationApplet(SelfRegistrationApplet.java:32)
    at SelfRegistrationApplet.init(SelfRegistrationApplet.java:26)
    at sun.applet.AppletPanel.run(AppletPanel.java:424)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at wizard.ModalFrameUtil$EventPump.start(ModalFrameUtil.java:80)
    at wizard.ModalFrameUtil.showAsModal(ModalFrameUtil.java:133)
    ... 8 more

您能否說出此調用有什么問題以及如何避免此異常?

這就是說Thread.currentThread()返回的Thread對象不是EventDispatchThread的實例。

為了避免這個問題的方法是找出哪些對象的類確實是,而且使用該類獲取Method的對象。 (通過在嘗試調用該方法的位置打印從Thread.currentThread().getClass()獲得的對象,您應該能夠找到它的含義。


用於invoke此內容的Javadoc表示:

“引發IllegalArgumentException如果該方法是一個實例方法,並且指定的對象參數不是聲明基礎方法(或其子類或實現者)的類或接口的實例;如果實際參數和形式參數的數量不同;如果原始參數的展開轉換失敗;或者在可能的展開之后,如果無法通過方法調用轉換將參數值轉換為相應的形式參數類型,則為錯誤。”

我對您的代碼的理解是,您擁有正確數量和類型的實際參數,因此線程類一定是一個問題。

AWT和swing GUI是單線程的,事件分發線程是應在其中運行所有GUI操作的特殊線程。 您的方法可能沒有在GUI線程上調用。 確保在事件分配線程上調用方法,可以這樣調用它

SwingUtilities.invokeAndWait(new Runnable(){public void run(){mymethod();}})

注意:javadocs不包含java.awt.EventDispatchThread因此您可能依賴一些實現細節。 您可以改用java.awt.EventQueueToolkit.getSystemEventQueue()的子類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM