NO IMAGE

    今天和一位朋友談到父類私有方法的呼叫問題,本來以為利用反射很輕鬆就可以實現,因為在反射看來根本不區分是否是private的,沒有想到呼叫本身的私有方法是可以的,但是呼叫父類的私有方法則不行,後來糾其原因很有可能是因為getDeclaredMethod方法和getMethod方法並不會查詢父類的私有方法,於是只好自己寫遞迴了,經過嘗試果然如此。把程式碼放出來方便更多人。這段程式碼可以解決很多實際問題,不過利用反射來做的話效能不會太好。

package com.syj.util.reflect;
import java.lang.reflect.Method;
/**
* 

* Title: 私有方法呼叫工具類
*

*
*

* Description:利用java反射呼叫類的的私有方法
*

*
*

* Copyright: Copyright (c) 2007
*

*
* @author 孫鈺佳
* @main [email protected]
* @date Jun 1, 2008 10:18:58 PM
*/
public class PrivateUtil {
/**
* 利用遞迴找一個類的指定方法,如果找不到,去父親裡面找直到最上層Object物件為止。
*
* @param clazz
* 目標類
* @param methodName
* 方法名
* @param classes
* 方法引數型別陣列
* @return 方法物件
* @throws Exception
*/
public static Method getMethod(Class clazz, String methodName,
final Class[] classes) throws Exception {
Method method = null;
try {
method = clazz.getDeclaredMethod(methodName, classes);
} catch (NoSuchMethodException e) {
try {
method = clazz.getMethod(methodName, classes);
} catch (NoSuchMethodException ex) {
if (clazz.getSuperclass() == null) {
return method;
} else {
method = getMethod(clazz.getSuperclass(), methodName,
classes);
}
}
}
return method;
}

/**
*
* @param obj
* 調整方法的物件
* @param methodName
* 方法名
* @param classes
* 引數型別陣列
* @param objects
* 引數陣列
* @return 方法的返回值
*/
public static Object invoke(final Object obj, final String methodName,
final Class[] classes, final Object[] objects) {
try {
Method method = getMethod(obj.getClass(), methodName, classes);
method.setAccessible(true);// 呼叫private方法的關鍵一句話
return method.invoke(obj, objects);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static Object invoke(final Object obj, final String methodName,
final Class[] classes) {
return invoke(obj, methodName, classes, new Object[] {});
}

public static Object invoke(final Object obj, final String methodName) {
return invoke(obj, methodName, new Class[] {}, new Object[] {});
}

/**
* 測試反射呼叫
*
* @param args
*/
public static void main(String[] args) {
PrivateUtil.invoke(new B(), “printlnA”, new Class[] { String.class },
new Object[] { “test” });
PrivateUtil.invoke(new B(), “printlnB”);
}
}

class A {
private void printlnA(String s) {
System.out.println(s);
}
}

class B extends A {
private void printlnB() {
System.out.println(“b”);
}
}

 

程式的輸出結果為
test
b
說明private方法呼叫成功了不管是自己的私有方法還是父類的私有方法。