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

我在第三方JAR设计得很差,我需要访问其中一个专用字段。 例如,为什么我需要选择私人领域是否有必要?

class IWasDesignedPoorly {
    private Hashtable stuffIWant;
}

IWasDesignedPoorly obj = ...;

我如何使用反射来获得stuffIWant的价值?


为了访问私有字段,您需要从类的声明字段中获取它们,然后使其可访问:

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

编辑 :由aperkins评论,既访问该字段,将其设置为可访问和检索值将全部抛出Exception s,虽然只需检查您需要注意的异常上面评论。

如果您通过与声明字段不对应的名称询问字段,则会引发NoSuchFieldException

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

如果该字段不可访问,则会抛出IllegalAccessException异常(例如,如果该字段是私有的,并且由于缺少f.setAccessible(true)行而无法访问f.setAccessible(true)

如果您尝试访问非字段类类型的对象的字段,则可能抛出的RuntimeExceptionSecurityException (如果JVM的SecurityManager不允许您更改字段的辅助功能)或IllegalArgumentException

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

尝试FieldUtils Apache的公地lang3:

FieldUtils.readField(object, fieldName, true);

反射并不是解决问题的唯一方法(即访问类/组件的私有功能/行为)

另一种解决方案是从.jar中提取类,使用(例如)Jode或Jad对其进行反编译,更改字段(或添加访问器),然后将其重新编译为原始.jar。 然后将新的.class放在类路径中的.jar之前,或者将它重新插入到.jar 。 (jar实用程序允许您提取并重新插入现有的.jar)

如下所述,这解决了访问/更改私人状态这一更广泛的问题,而不是简单地访问/更改字段。

这需要.jar当然不能被签名。

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

上一篇: How to read the value of a private field from a different class in Java?

下一篇: JSONP inner workings with AJAX