所有编译时常量都是内联的吗?
假设我有一个这样的类:
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";
}
我的应用程序中的许多其他类都在使用这些选项。 现在,我想单独更改其中一个选项并仅部署已编译的类。 但如果这些字段内嵌在消费者类中,这就不可能了,对吗?
是否有任何选项可以禁用编译时常量的内联?
Let's say I have a class like this:
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";
}
Many of the other classes in my application are using these options. Now, I want to change one of the options alone and deploy just the compiled class.
But if these fields are in-lined in the consumer classes this becomes impossible right?
Is there any option to disable the in-lining of compile time constants?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用 String.intern() 来获得所需的效果,但应该注释您的代码,因为没有多少人知道这一点。 即
这将阻止编译时内联。 由于它引用编译器将放置在 perm 中的完全相同的字符串,因此您不会创建任何额外的内容。
作为替代方案,您始终可以这样做
,这可能更容易阅读。 不管怎样,因为这有点奇怪,你应该对代码进行注释,以告知维护它的人你正在做什么。
编辑:
找到了另一个 SO 链接,其中提供了对 JLS 的引用,以获取有关此内容的更多信息。
何时对字符串文字使用 intern()
You can use String.intern() to get the desired effect, but should comment your code, because not many people know about this. i.e.
This will prevent the compile time inline. Since it is referring to the exact same string that the compiler will place in the perm, you aren't creating anything extra.
As an alternative you could always do
which might be easier to read. Either way, since this is a bit odd you should comment the code to inform those maintaining it what you are doing.
Edit:
Found another SO link that gives references to the JLS, for more information on this.
When to use intern() on String literals
不,恐怕它是 JLS 的一部分。 Java Puzzlers 中对此进行了简要介绍,但我手头没有副本。
我想您可能会考虑在属性文件中定义这些常量,并拥有定期加载它们的类。
参考: http://java.sun.com/docs /books/jls/third_edition/html/expressions.html#5313
No, it's part of the JLS, I'm afraid. This is touched upon, briefly, in Java Puzzlers but I don't have my copy to hand.
I guess you might consider having these constants defined in a properties file, and have the class that loads them periodically.
Reference: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
不,您可以用静态方法调用替换它们,例如:
当然,它并不漂亮,但它可以满足您的要求。 :)
No. You could replace them with a static method call, though, like:
Granted, it’s not beautiful but it would fulfill your requirement. :)
实际上,如果您删除
final
关键字,常量将不再是编译时常量,然后您的配置将按您想要的方式工作。但是,强烈建议如果这确实是您尝试执行的某种配置,那么您应该采用比某些类文件中的常量更易于管理的方式。
Actually, if you remove the
final
keyword the constants stop being compile-time constants and then your configuration will work like you want.However, it is strongly suggested that if this is indeed some sort of configuration you are trying to do, you should move to to a more manageable way than constants in some class file.
您可以通过将常量设置为非编译时常量来禁止内联...
例如,
null
不是编译时常量。 任何涉及非编译时常量的表达式都不是编译时常量,尽管 javac 可以在编译单元内进行常量折叠。You can inhibit inlining by making your constant non-compile time constants...
For instance,
null
is not a compile time constant. Any expression involving a non-compile time constant is not a compile time constant, although javac may do constant folding within the compilation unit.这里没有任何内容表明这些值应该内联。 您只是声明一些
public
、static
成员。 其他类正在使用这些成员的值。 不要求内联。 即使是final
关键字,但出于性能原因,某些 JVM 可能会在其他类中内联这些值。 这是一个优化。 任何优化都不应改变程序的行为。 因此,如果更改这些成员的定义,JVM 应该取消内联以前的值。
这就是为什么无法关闭内联的原因。 要么JVM不内联并且没有问题,要么如果内联,JVM保证不内联。
我不确定当您静态导入此类时会发生什么。 我认为(不确定)内联已执行,可能会导致您提到的麻烦。 如果是这种情况,您基本上可以删除静态导入,就可以了。
There is nothing here that says these values should be inlined. You are just declaring some
public
,static
members. Those other classes are using the values of these members. No inlining is asked. Even thefinal
keywordBut for performance reasons, some JVMs may inline these values in those other classes. This is an optimization. No optimization should change the behaviour of a program. So if you change the definition of these members, the JVM should un-inline the previous values.
This is why there is no way to turn inlining off. Either the JVM does not inline and there is no problem or if it is inlined, the JVM guarantee the un-inlining.
I am not sure what happens when you import statically this class. I think (not sure) the inlining is performed and may cause the trouble you mention. If that is the case, you could basically delete the static import and you are ok.