How to read the value of a private field from a different class in Java?
Как прочитать значение закрытого поля из другого класса в Java?
У меня плохо спроектированный класс от стороннего разработчика JAR и мне нужно получить доступ к одному из его закрытых полей. Например, зачем мне нужно выбирать закрытое поле, это обязательно?
РЕДАКТИРОВАТЬ: как было прокомментировано аперкинсом, доступ к полю, установка его как доступного и извлечение значения могут вызвать Exceptions, хотя единственные проверенные исключения, о которых вам нужно помнить, прокомментированы выше.
NoSuchFieldException Будет выдано, если вы запросите поле по имени, которое не соответствует объявленному полю.
IllegalAccessException Будет выдано, если поле недоступно (например, если оно закрыто и не было сделано доступным из-за пропуска f.setAccessible(true) строки.
RuntimeExceptionS, которые могут быть выданы, являются либо SecurityExceptions (если JVM SecurityManager не позволит вам изменить доступность поля), либо IllegalArgumentExceptions, если вы попытаетесь получить доступ к полю в объекте, отличном от типа класса поля:
f.get("BOB"); //will throw IllegalArgumentException, as String is of the wrong type
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.
Ответ 4
One other option that hasn't been mentioned yet: use Groovy. Groovy allows you to access private instance variables as a side effect of the design of the language. Whether or not you have a getter for the field, you can just use