I am not sure how good or bad this idea is (leaning more towards bad as it breaks encapsulation) but coming from a Ruby perspective, I like to have the option of accessing private members of a class if I really really want to ("shooting yourself in the foot" as it is called).
Keeping that ideological discussion aside (although I'd appreciate any comments/opinions on this), especially since I'd use such code only in tests (and even when using it there, try avoiding it as a deodorant for "code smells", imho), lemme get down to code. I have created a Violator class that allows you to set values on private fields of an object, given that you know the field name (again, using string literals to refer to field names is a bad idea as it hampers refactoring but I'll leave aside that discussion too):
import java.lang.reflect.Field; // Understands how to violate encapsulation public class Violator { private Object obj; public Violator(Object objectToViolate) { this.obj = objectToViolate; } public void setFieldOnObject(String fieldName, Object value) throws NoSuchFieldException { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); try { field.set(obj, value); } catch(IllegalAccessException illegalAccessException) { throw new RuntimeException("Could not set value on field " + fieldName + " for object " + obj, illegalAccessException); } } }
Here's the unit test for the same:
import junit.framework.TestCase; public class ViolatorTest extends TestCase { public void testShouldSetValueOnPrivateFieldOfObject() throws NoSuchFieldException { class ObjectWithPrivateField { private int privateField = 10; public int privateField() { return privateField; } } ObjectWithPrivateField objectWithPrivateField = new ObjectWithPrivateField(); new Violator(objectWithPrivateField).setFieldOnObject("privateField", 99); assertEquals(99, objectWithPrivateField.privateField()); } public void testShouldThrowExceptionOnUnknownField() { class ObjectWithoutField { } Violator violator = new Violator(new ObjectWithoutField()); try { violator.setFieldOnObject("someField", "some value"); fail("should throw exception"); } catch(NoSuchFieldException noSuchFieldException) { // expected } } }
Most of the above is standard Java reflection. The magic lies basically in this one statement: field.setAccessible(true);
Enhancing the Violator to return values of private members is equally easy and is left as an exercise for my readers.
Remember to TDD!