Skip to content

Instantly share code, notes, and snippets.

@bmaggi
Created July 8, 2016 12:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmaggi/d09d7c100dc8437704b95f48648e978e to your computer and use it in GitHub Desktop.
Save bmaggi/d09d7c100dc8437704b95f48648e978e to your computer and use it in GitHub Desktop.
Introspection example to change private field and call private method
public class Account {
// #1 : Safe private field...
private long myMoney;
public Account() {
this.myMoney = 100;
}
public long getMoney(){
return myMoney;
}
// #2 : Safe private method...
private void resetAccount(){
myMoney = 0;
}
}
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class AccountHackUtil {
// Change a private field
public static void changeField(Object object,String fieldName,Object newValue) throws IllegalArgumentException, IllegalAccessException {
Class<?> objectClass = object.getClass();
Field[] fields = objectClass.getDeclaredFields();
for (Field field : fields) {
String localFieldName = field.getName();
if (fieldName.equals(localFieldName)){
field.setAccessible(true);
field.set(object, newValue);
}
}
}
// call a private method
public static void changeMethod(Object object,String methodName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class<?> objectClass = object.getClass();
Method[] methods = objectClass.getDeclaredMethods();
for (Method method : methods) {
String name = method.getName();
if (methodName.equals(name)){
method.setAccessible(true);
method.invoke(object);
}
}
}
}
import java.lang.reflect.InvocationTargetException;
import org.junit.Assert;
import org.junit.Test;
public class AccountTest {
@Test
public void changeAccountMoneyField() throws IllegalArgumentException, IllegalAccessException {
Account account = new Account();
Assert.assertEquals(100, account.getMoney());
AccountHackUtil.changeField(account, "myMoney", 0);
Assert.assertEquals(0, account.getMoney());
}
@Test
public void callAccountResetMethod() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Account account = new Account();
Assert.assertEquals(100, account.getMoney());
AccountHackUtil.changeMethod(account, "resetAccount");
Assert.assertEquals(0, account.getMoney());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment