如何从Java中的抽象类改变私有字段?

发布于 2024-07-30 04:33:00 字数 984 浏览 4 评论 0原文

有一个抽象类:

public abstract class AbstractAny {
  private long period;

  public void doSomething() {
    // blah blah blah
    period = someHardcodedValue;
    // blah blah blah
  }
}

我不想更改抽象类的源,但需要在如何设置字段周期方面添加一些灵活性。 是否可以通过重写方法更改字段周期的值? 例如:

public class ConcreteSome extends AbstractAny{
  @Override
  public void doSomething() {
    try {
      Field p = super.getClass().getDeclaredField("period");
      p.setAccessible(true);
      p.setLong(this, 10L);
    } catch (SecurityException e) {
        throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
  }
}

当我尝试运行此代码时 super.getClass().getDeclaredField("period") 抛出 java.lang.NoSuchFieldException: period

There's an abstract class:

public abstract class AbstractAny {
  private long period;

  public void doSomething() {
    // blah blah blah
    period = someHardcodedValue;
    // blah blah blah
  }
}

I don't want to change the source of the abstract class but need to add some flexibility on how the field period is being set. Is it possible to change the value of the field period from an overriden method? Like for example:

public class ConcreteSome extends AbstractAny{
  @Override
  public void doSomething() {
    try {
      Field p = super.getClass().getDeclaredField("period");
      p.setAccessible(true);
      p.setLong(this, 10L);
    } catch (SecurityException e) {
        throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
  }
}

When I try to run this code super.getClass().getDeclaredField("period") throws java.lang.NoSuchFieldException: period

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

注定孤独终老 2024-08-06 04:33:00

您需要 getClass().getSuperclass() 来获取超类,而不是 super.getClass()

但是,我真的不建议这样做。 您基本上破坏了抽象类的封装。 如果抽象类没有为其后代提供足够的灵活性,则应该对其进行修复 - 绕过它只是自找麻烦。 如果每当这个抽象类的其他成员需要更改时,该怎么办? 拥有私有状态的全部目的是让类能够保护自己的数据。 像这样使用反射是一个非常丑陋的黑客,这应该是绝对的最后手段。

You need getClass().getSuperclass() to get the superclass, not super.getClass().

However, I really don't recommend doing this. You're basically destroying the encapsulation of the abstract class. If the abstract class isn't providing enough flexibility for its descendants, it should be fixed - going around it is just asking for trouble. What if some other member of the abstract class needs to be changed whenever this one does? The whole point of having private state is so that the class is able to guard its own data. Using reflection like this is a really ugly hack which should be an absolute last resort.

寄与心 2024-08-06 04:33:00

我和乔恩·斯基特在一起。 从长远来看,更改超类的源代码以保护该字段或将突变委托给可重写的方法会更容易。 使用反射来更改值现在可以正常工作,但随着时间的推移,它的扩展性不太好。

I'm with Jon Skeet. It's easier in the long run to change the superclass's source code to either make this field protected or to delegate mutation to an overridable method. Using reflection to change the value works ok now, but it doesn't scale very well as far as maintenance over time goes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文