假设我有一堂这样的课:

class ApplicationDefs{
public static final String configOption1 = "some option";
public static final String configOption2 = "some other option";
public static final String configOption3 = "yet another option";
}

我的应用程序中的许多其他类都在使用这些选项。现在,我想单独更改其中一个选项并仅部署已编译的类。但如果这些字段内嵌在消费者类中,这就不可能了,对吧?

是否有任何选项可以禁用编译时常量的内联?

有帮助吗?

解决方案

您可以使用string.intern()获得所需的效果,但应该评论您的代码,因为没有多少人知道这一点。 IE

public static final String configOption1 = "some option".intern();

这将防止编译时间内联。由于它指的是编译器将放置在PERM中的完全相同的字符串,因此您不会创建任何额外的内容。

作为替代方案,您总是可以做

public static final String configOption1 = "some option".toString();

但是,这不会使用编译的实习生字符串,它将在旧的Gen上创建一个新的字符串。没什么大不了的,可能更容易阅读。无论哪种方式,由于这有点奇怪,您都应该评论代码,以告知那些维护您正在做的事情。

编辑:找到了另一个链接,可以引用JLS,以获取有关此信息的更多信息。何时在字符串文字上使用intern()

其他提示

不,恐怕这是JLS的一部分。简而言之,这是在Java Puplers中涉及的,但我没有副本可以交付。

我想您可能会考虑在属性文件中定义这些常数,并将其定期加载的类。

参考: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313

不。但是,您可以用静态方法调用代替它们,例如:

class ApplicationDefs {

    public static String configOption1() { return "some option"; }

}

当然,它不是美丽的,但可以满足您的要求。 :)

实际上,如果你 去除 final 关键词 常数停止编译时间常数,然后是您的配置 将工作 像你要的那样。

但是,强烈建议,如果这确实是您要执行的某种配置,那么您应该比某些类文件中的常量更易于管理。

您可以通过使您的持续非编译时间常数来抑制内部...

例如, null 不是编译时间常数。尽管Javac可以在编译单元内进行恒定折叠,但涉及非编译时间常数的任何表达都不是编译时间常数。

public static final String configOption1 = null!=null?"": "some option";

这里没有任何内容表明这些值应该内联。你只是声明一些 public, static 成员。其他类正在使用这些成员的值。不要求内联。即便是 final 关键词

但对于 性能原因, ,一些 JVM 可能 排队 这些值在其他类中。这是一个优化。任何优化都不应改变程序的行为。因此,如果更改这些成员的定义,JVM 应该 非内联 之前的值。

这就是为什么无法关闭内联的原因。要么JVM不内联并且没有问题,要么如果内联,JVM保证不内联。

我不确定当您静态导入此类时会发生什么。我认为(不确定)内​​联已执行,可能会导致您提到的麻烦。如果是这种情况,您基本上可以删除静态导入,就可以了。

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