【问题标题】:reload a class so its static members are re-initialized重新加载一个类,使其静态成员重新初始化
【发布时间】:2014-01-04 07:54:02
【问题描述】:

假设我有一个像下面这样的类

public class Foo
{
     public static final String FIELD_1 = Env.getProperties("one");
     public static final String FIELD_2 = Env.getProperties("one");

     //....
     public static final String FIELD_N = Env.getProperties("n");
}

显然,当我们第一次引用Foo 时,所有FIELD_* 都会被填充。 假设我的Env.getProperties(String) 不是纯粹的函数式(即,它可以返回不同的值。如何?这里不重要)

如何强制“重新加载”类 Foo,以便重新执行所有类初始化代码(这样我可以为静态字段设置不同的值)?

(由于各种原因,我无法将这些字段设为非静态或非最终字段。 所以请不要建议像让 Foo 成为接口这样的解决方案,并覆盖各种 getter 方法)

谢谢

【问题讨论】:

  • 我的错,我没有注意到 Final 关键字。答案已删除。
  • 如果我没听错的话,你想要一些状态的快照吗?
  • 嗯,不,对不起。我希望能够更改这些字段的值,以便调用者可以看到新值。
  • 我认为如果我们了解上下文,我们会更容易为您提供帮助。我很抱歉这么说,但你会得到的建议不会使用静态。 ;)
  • 所以也许没有你会接受的解决方案。

标签: java dynamic-class-loaders


【解决方案1】:

别这样!

您也许可以使用自定义类加载器或 JRebel 来实现,但这将是一个巨大的障碍。不同的类可能从这些字段中读取了不同的值并且彼此不同步等。

常数应该是常数。遵循principle of least astonishment 并重构为更好的设计。


最少的重构建议

如果这些字段的名称合理 - FIELD_1FIELD_2 等 - 您可以在所有 Java 文件中搜索和替换对它们的引用,并使用 FIELD_1()FIELD_2()。然后写一些代码来用静态方法替换常量:

public static String FIELD_1() { return Env.getProperties("one"); }
public static String FIELD_2() { return Env.getProperties("two"); }
//etc.

它有点难看,但它会让你到达你想去的地方,而不需要求助于真正的黑客。

【讨论】:

  • 不同的调用者得到不同的值不是问题(因为这正是我想要的)。
  • @aetheria OP 可能只是下一个男人或女孩,因为以前的编码员决定这样做......
  • @OneTwoThree 对我来说这听起来像是有问题的设计。我不知道这些“各种原因”是什么,但如果您可以选择在不破坏十几个应用程序的情况下改进设计,我会考虑改进设计。糟糕的设计通常总是在以后成为一个问题,当它真的很难改变时。
  • 好吧,好吧,我承认这些“各种原因”包括“这个文件有 3,000 多行,包含(尽可能多的字段)。而且我不想重写所有这些。 (这还不包括来电者)”
  • 我对你有感觉!你能写一些代码来重构 Java 文件吗?即读入Java文件,改变访问字段的方式并写出新版本?至少那时这不是手动操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
相关资源
最近更新 更多