簡體   English   中英

如何使用反射使用.class(非對象)參數調用Java中的方法

[英]How to invoke a method in java with .class (non-object) parameters using reflection

最近,我不得不使用反射來訪問超類中的一些私有方法和字段。 這是我開始使用反射之前的樣子:

            processSecondPassesOfType(PkDrivenByDefaultMapsIdSecondPass.class);
        processSecondPassesOfType(SetSimpleValueTypeSecondPass.class);
        processSecondPassesOfType(CopyIdentifierComponentSecondPass.class);
        processFkSecondPassInOrder();
        processSecondPassesOfType(CreateKeySecondPass.class);
        processSecondPassesOfType(SecondaryTableSecondPass.class);

現在,我必須調用通過反射獲取的私有方法:

        Class<?> clazz = Class.forName("org.hibernate.cfg.Configuration");
        inSecondPass = true;
        Method m1 = clazz.getDeclaredMethod("processSecondPassesOfType", Class.class);
        m1.setAccessible(true);
        m1.invoke(PkDrivenByDefaultMapsIdSecondPass.class);

當我嘗試運行此命令時,出現以下錯誤:

java.lang.IllegalArgumentException: object is not an instance of declaring class

那么,如何使用反射調用具有非對象參數的方法?

除非這是一個靜態方法-你需要的實例來調用

在普通代碼中,您可以執行以下操作:

foo.bar(x, y, z); 

foo上調用bar()

使用反射,邏輯會在某種程度上被逆轉:

handleToBar = ...
handleToBar.invoke(foo, x, y, ...

換句話說:您不能“憑空”調用非靜態方法。 您必須提供一些對象來調用。

當然,通常的免責聲明是:A)反射是“邪惡的” B)僅在絕對必要時使用它,然后C)知道自己在做什么,D)避免調用私有的東西-這些是實現細節和主題改變。 您只能在運行時找到它,因為A)反射是“邪惡的”。

m1.invoke(PkDrivenByDefaultMapsIdSecondPass.class);

當使用java.lang.reflect.Method.invoke() 調用方法時,第一個參數是要在其上調用此特定方法的對象實例。 (如果該方法是靜態的,則第一個參數應為null。)后續參數是該方法的參數。

因此,如果被調用的方法是靜態的,則調用將為;

m.invoke(null, methodArguments);

如果被調用的方法不是靜態的,則調用將為;

m.invoke(objectOnWhichMethodCalled, methodArguments);

如果基礎方法引發異常,則它將被java.lang.reflect.InvocationTargetException包裝。 可以使用異常鏈接機制的InvocationTargetException.getCause()方法來檢索該方法的原始異常。

暫無
暫無

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

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