How to read the value of a private field from a different class in Java?

I have a poorly designed class in a 3rd-party JAR and I need to access one of its private fields. For example, why should I need to choose private field is it necessary?

class IWasDesignedPoorly {
    private Hashtable stuffIWant;
}

IWasDesignedPoorly obj = ...;

How can I use reflection to get the value of stuffIWant ?


In order to access private fields, you need to get them from the class's declared fields and then make them accessible:

Field f = obj.getClass().getDeclaredField("stuffIWant"); //NoSuchFieldException
f.setAccessible(true);
Hashtable iWantThis = (Hashtable) f.get(obj); //IllegalAccessException

EDIT : as has been commented by aperkins, both accessing the field, setting it as accessible and retrieving the value will all throw Exception s, although the only checked exceptions you need to be mindful of are commented above.

The NoSuchFieldException would be thrown if you asked for a field by a name which did not correspond to a declared field.

obj.getClass().getDeclaredField("misspelled"); //will throw NoSuchFieldException

The IllegalAccessException would be thrown if the field was not accessible (for example, if it is private and has not been made accessible via missing out the f.setAccessible(true) line.

The RuntimeException s which may be thrown are either SecurityException s (if the JVM's SecurityManager will not allow you to change a field's accessibility), or IllegalArgumentException s, if you try and access the field on an object not of the field's class's type:

f.get("BOB"); //will throw IllegalArgumentException, as String is of the wrong type

尝试FieldUtils Apache的公地lang3:

FieldUtils.readField(object, fieldName, true);

Reflection isn't the only way to resolve your issue (which is to access the private functionality/behaviour of a class/component)

An alternative solution is to extract the class from the .jar, decompile it using (say) Jode or Jad, change the field (or add an accessor), and recompile it against the original .jar. Then put the new .class ahead of the .jar in the classpath, or reinsert it in the .jar . (the jar utility allows you to extract and reinsert to an existing .jar)

As noted below, this resolves the wider issue of accessing/changing private state rather than simply accessing/changing a field.

This requires the .jar not to be signed, of course.

链接地址: http://www.djcxy.com/p/8354.html

上一篇: 为什么C ++没有反射?

下一篇: 如何从Java中的不同类读取私有字段的值?