[英]How to call a private method that exists inside a private inner class
我想測試一個私有內部類中存在的私有方法
public class MyBigClass {
private class MyInnerClass {
private void wantedMethod() {
}
}
}
我想調用wantedMethod()
來測試它
這是我的代碼
Class[] classes = MyBigClass.class.getDeclaredClasses();
for (int i = 0; i < classes.length; i++) {
// this code print "MyInnerClass"
System.out.println(">> inner classes >> " + classes[i].getSimpleName());
if (classes[i].getSimpleName().equals("MyInnerClass")) {
Class clazz = classes[i];
// Constructor c=clazz.getConstructor();
Method[] methods = clazz.getDeclaredMethods();
// this code print "wantedMethod"
for (int j = 0; j < methods.length; j++) {
System.out.println("inner class methods >> " + methods[i].getName());
}
}
}
問題 :我無法調用wantedMethod()
如果要調用非靜態方法,則需要告知要調用它的對象。 在您的情況下,您需要內部類對象,但由於您還沒有內部類對象,因此您需要創建它。 由於Java不能在沒有外部類對象的情況下創建內部類對象,因此您還需要創建該外部對象。
所以這些是您需要采取的步驟:
你可以這樣做:
(你只需要記住默認構造函數與其類的可見性具有相同的可見性,因此私有類將具有私有構造函數,在我們能夠使用它之前我們需要使它們可訪問)
try {
//creating parent object
Object outer = new MyBigClass();
//creating inner class object
Class<?> innerClass = Class.forName("MyBigClass$MyInnerClass");
Constructor<?> constructor = innerClass.getDeclaredConstructor(MyBigClass.class);//inner object must know type of outer class
constructor.setAccessible(true);//private inner class has private default constructor
Object child = constructor.newInstance(outer);//inner object must know about its outer object
//invoking method on inner class object
Method method = innerClass.getDeclaredMethod("wantedMethod",new Class<?>[]{});
method.setAccessible(true);//in case of unaccessible method
method.invoke(child,new Object[]{});
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
您可以在此問題中找到有關通過反射創建內部類對象的更多信息
這是因為您的類未命名為CodeCircuit
。 刪除if
條件,它將工作。
同時刪除行Constructor c=clazz.getConstructor();
因為它拋出異常。
進行這些更改后,將打印您自己的代碼
>> inner classes >> MyInnerClass
inner class methods >> wantedMethod
使用此代碼執行該方法。
Class<?>[] classes = MyBigClass.class.getDeclaredClasses();
for (Class<?> clazz : classes) {
if(clazz.getSimpleName().equals("MyInnerClass")) {
Method method = clazz.getDeclaredMethod("wantedMethod", new Class[] {});
method.setAccessible(true);
method.invoke(clazz.getDeclaredConstructor(MyBigClass.class).newInstance(new MyBigClass()), new Object[] {});
}
}
語法有點奇怪,使您可以使用外部類來獲取內部類構造函數。 它的行為就好像你有一個構造函數,在你的內部類中定義了以下簽名:
public MyInnerClass(MyBigClass bigClass) {
}
但是,我認為這是Java如何使用反射處理內部(嵌套)類。
請注意,您必須為內部類提供public
構造函數。
public class MyBigClass {
private class MyInnerClass {
public MyInnerClass() {
System.out.println("hello");
}
private void wantedMethod() {
System.out.println("world");
}
}
}
您還必須在私有方法上設置setAccessible(true)
才能調用它。
經過進一步調查,當我反編譯生成的MyBigClass$MyInnerClass.class
類時,我發現我的預感是正確的:
public class MyBigClass$MyInnerClass {
public MyBigClass$MyInnerClass(MyBigClass paramMyBigClass) {
System.out.println("hello");
}
private void wantedMethod() {
System.out.println("world");
}
}
如果有人可以對這種行為有所啟發,那真的很高興
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.