所有编译时常量都是内联的吗?
-
22-08-2019 - |
题
假设我有一堂这样的课:
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保证不内联。
我不确定当您静态导入此类时会发生什么。我认为(不确定)内联已执行,可能会导致您提到的麻烦。如果是这种情况,您基本上可以删除静态导入,就可以了。