【问题标题】: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;
   }
}

【问题讨论】:

  • 如果问题的代码中包含“我试过这个...”,问题会得到很大改善。
  • 这个问题是骗人的——它已经被问了好几次了

标签: java reflection


【解决方案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 字段的值。

【讨论】:

    猜你喜欢
    • 2015-07-08
    • 2011-04-03
    • 2010-12-18
    • 2010-11-17
    • 1970-01-01
    • 2020-08-04
    • 2010-12-06
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多