有一个抽象类:

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

有帮助吗?

解决方案

您需要getClass().getSuperclass()得到超,不是super.getClass()

不过,我的真正的不建议这样做。你基本上摧毁了抽象类的封装。如果抽象类没有提供足够的灵活性,它的后代,它应该是固定的 - 到处是自找麻烦。如果有什么需要抽象类的其他成员,只要这个人做改变?具有私有状态的全部意义在于,使类能够保护其自己的数据。使用反射像这是一个非常丑陋的黑客应该是一个绝对的最后的度假胜地。

其他提示

我与乔恩斯基特。这是从长远来看更容易超类的源代码更改为使这一领域的保护或委托突变可重写的方法。使用反射来改变值现在工程确定,但就维修过时间的推移它没有很好地进行缩放。

ConcreteSome未延伸的抽象类AbstractAny。结果 尝试这种

public class ConcreteSome {
    @Override
    public void doSomething() {
        Class<?> clazz = getClass().getSuperclass();
        System.out.println(clazz);
        Field p = clazz.getDeclaredField("period");
        ...

应该返回java.lang.Object中

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top