How can I access an inherited protected field from an object by reflection?
field = myclass.getDeclaredField("myname");
field.setAccessible(true);
field.set(myinstance, newvalue);
Do you perhaps mean from a different object an untrusted context with a SecurityManager
set? That would break the type system, so you can't. From a trusted context, you can call setAccessible
to defeat the type system. Ideally, don't use reflection.
You could do something like...
Class clazz = Class.forName("SuperclassObject");
Field fields[] = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals("fieldImLookingFor")) {
field.set...() // ... should be the type, eg. setDouble(12.34);
}
}
You might also need to change the accessibility, as noted in Maurice's answer.
Two issues you may be having issues with - the field might not be accessible normally (private), and its not in the class you are looking at, but somewhere up the hierarchy.
Something like this would work even with those issues:
public class SomeExample {
public static void main(String[] args) throws Exception{
Object myObj = new SomeDerivedClass(1234);
Class myClass = myObj.getClass();
Field myField = getField(myClass, "value");
myField.setAccessible(true); // required if field is not normally accessible
System.out.println("value: " + myField.get(myObj));
}
private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
}
class SomeBaseClass {
private Integer value;
SomeBaseClass(Integer value) {
this.value = value;
}
}
class SomeDerivedClass extends SomeBaseClass {
SomeDerivedClass(Integer value) {
super(value);
}
}
Use reflection to access the members of the class instance, make them accessible and set their respective values. Of course you'd have to know the name of each member you want to change, but I guess that won't be a problem.
public class ReflectionUtil {
public static Field getField(Class clazz, String fieldName) throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
public static void makeAccessible(Field field) {
if (!Modifier.isPublic(field.getModifiers()) ||
!Modifier.isPublic(field.getDeclaringClass().getModifiers()))
{
field.setAccessible(true);
}
}
}
public class Application {
public static void main(String[] args) throws Exception {
KalaGameState obj = new KalaGameState();
Field field = ReflectionUtil.getField(obj.getClass(), 'turn');
ReflectionUtil.makeAccessible(field);
field.setInt(obj, 666);
System.out.println("turn is " + field.get(obj));
}
}