Created
July 8, 2016 12:01
-
-
Save bmaggi/d09d7c100dc8437704b95f48648e978e to your computer and use it in GitHub Desktop.
Introspection example to change private field and call private method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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