Sometimes, we need operate private member from outer without modifying source , we canuse java reflect to do it , The document will introduce how to do it.
Get private inner class instance and exec itsfunction
Samplecode like below:
public class StorageServerPmTraffic {
//…
static class MySettingListener implements MTValueSettingFailureListener
{
static MTValueSettingFailureInfo failedInfo;
public void notifyValueSettingFailureResult(MTValueSettingFailureInfo result)
{
//…
}
}
//…
}
we shall execute notifyValueSettingFailureResult , at first , we should get a instance of outer class (StorageServerPmTraffic)and get its inner class (MySettingListener)
//new outer class instance
StorageServerPmTraffic sspt = new StorageServerPmTraffic();
//get inner class handle
Class<?> cInner = sspt.getClass().getDeclaredClasses()[0];
cInnerrepresent inner class MySettingListener. And then , get inner class construct func and set its accessible to true:
Constructor<?> c = cInner.getDeclaredConstructors()[0];
//let me have access right
c.setAccessible(true);
fetchfunction we want to execute , we care “notifyValueSettingFailureResult” :
// get func (notifyValueSettingFailureResult) handle , arg1 is func name you want to get , arg2 is the func’s argument type
method = cInner.getDeclaredMethod(methodName, MTValueSettingFailureInfo.class);
//execute MySettingListener.notifyValueSettingFailureResult
method.invoke(c.newInstance(new Object[]{}) , info);
invokewill execute inner class func , arg 1 isinstance of inner class, arg 2 is innerclass func’s arg ( MySettingListener.notifyValueSettingFailureResult)
Get privatefield value and set it
Inthis condition , we try to get private member variable , and reset its value , itis another way to get class handle , codelike below:
package ericsson.ipworks.storage.server.cba.pm;
//…
public class StorageServerPmTraffic {
private static Gauge EnumDnSchedNumbergauge;
private static Gauge EnumDnRangeNumbergauge;
//…
}
We shall get EnumDnSchedNumbergauge , first , we use absolute class path to getclass handle
cls = Class.forName("ericsson.ipworks.storage.server.cba.pm.StorageServerPmTraffic");
and then , get Specified field handle , set its accessible to true:
Field field = cls.getDeclaredField("EnumDnSchedNumbergauge");
field.setAccessible(true);
getfield value , it is a object type:
Object Schedgauge = field.get(cls);
We can enforce to cast it to Gauge type like below:
Gauge result = (Gauge)Schedgauge;
Ishall set the result to EnumDnRangeNumbergauge , get its field handle:
Field fieldRange = cls.getDeclaredField("EnumDnRangeNumbergauge");
fieldRange.setAccessible(true);
setfieldRange to result , arg1 is StorageServerPmTraffic instance you want to set
fieldRange.set(sspt, result);