Java中是不是可以通过反射访问私有字段[重复]
Posted
技术标签:
【中文标题】Java中是不是可以通过反射访问私有字段[重复]【英文标题】:Is it possible in Java to access private fields via reflection [duplicate]Java中是否可以通过反射访问私有字段[重复] 【发布时间】:2010-12-06 01:17:44 【问题描述】:在 Java 中是否可以通过反射访问私有字段 str? 例如获取该字段的值。
class Test
private String str;
public void setStr(String value)
str = value;
【问题讨论】:
如果问题的代码中包含“我试过这个...”,问题会得到很大改善。 这个问题是骗人的——它已经被问了好几次了 【参考方案1】:是的,这绝对是 - 假设您拥有适当的安全权限。如果您从其他类访问它,请先使用Field.setAccessible(true)
。
import java.lang.reflect.*;
class Other
private String str;
public void setStr(String value)
str = value;
class Test
public static void main(String[] args)
// Just for the ease of a throwaway test. Don't
// do this normally!
throws Exception
Other t = new Other();
t.setStr("hi");
Field field = Other.class.getDeclaredField("str");
field.setAccessible(true);
Object value = field.get(t);
System.out.println(value);
不,你通常不应该这样做......它颠覆了课程原作者的意图。例如,很可能在可以正常设置字段的任何情况下应用验证,或者可以同时更改其他字段。您实际上违反了预期的封装级别。
【讨论】:
正如 Jon 所指出的,在极少数情况下您应该这样做。不幸的是,我不得不做的事情比我愿意承认的要多,这使得代码非常难看。 很好的修正。 (参见 Java 编程语言安全编码指南 2.0 版的指南 6-4:java.sun.com/security/seccodeguide.html) @Downvoter:想解释一下原因吗? @JonSkeet 为什么java允许它访问私有成员?为什么java创建setAccessible()
方法?
@IslamEl-Rougy:对于其他烦人的情况,反射通常是一种实用的解决方案。在可能的情况下绝对值得避免,而且通常是一个糟糕的解决方案。我不知道我是否会完全禁止它,但我至少总是会感到紧张。【参考方案2】:
是的。
Field f = Test.class.getDeclaredField("str");
f.setAccessible(true);//Very important, this allows the setting to work.
String value = (String) f.get(object);
然后你使用字段对象来获取类实例的值。
请注意,get 方法通常会让人们感到困惑。您有该字段,但您没有该对象的实例。您必须将其传递给 get
方法
【讨论】:
object
是什么??
@Gevorg 它是一个引用变量,指向具有私有字段的类的实例。【参考方案3】:
是的,这是可能的。
您需要使用 getDeclaredField 方法(而不是 getField 方法),并带有您的私有字段的名称:
Field privateField = Test.class.getDeclaredField("str");
此外,如果您想访问私有字段,您需要将此字段设置为可访问:
privateField.setAccessible(true);
完成后,您可以使用 Field 实例的 get 方法来访问 str 字段的值。
【讨论】:
以上是关于Java中是不是可以通过反射访问私有字段[重复]的主要内容,如果未能解决你的问题,请参考以下文章