【问题标题】:Compiler optimization of public static final and OSGipublic static final 和 OSGi 的编译器优化
【发布时间】:2012-05-10 06:52:38
【问题描述】:

我有一个使用

导出类的 OSGi 包 b1
public static final String MYVAL = "a"; //version 1

第二个包 b2 使用 b1 的版本 1 编译和部署。

稍后我将 b1 中的值更改为

public static final String MYVAL = "b"; //version 2

但是我只重新编译部署b1,b2不变,没有重新编译。

b2 是否有可能在运行时仍然看到值 a

【问题讨论】:

    标签: java osgi compiler-optimization


    【解决方案1】:

    引用的静态最终原语或字符串的值直接内联到使用类中。因此与 OSGI 和任何可见性规则无关,b2 仍将包含嵌入的 MYVAL 值“a”。

    我认为这记录在Java Language Specification, Section 13.4:

    如果一个字段是一个常量变量(第 4.12.4 节),那么删除关键字 final 或更改其值不会因为导致它们不运行而破坏与预先存在的二进制文件的兼容性,但 他们不会看到除非重新编译,否则字段使用的任何新值。即使用法本身不是编译时常量表达式(第 15.28 节)也是如此。

    This answer to a similar question 显示了一种解决方法。更改声明使其不再是常量表达式会禁用此内联行为。

    public static final String MYVAL = String.valueOf("a");
    

    【讨论】:

    • 您应该能够避免使用新的 String 对象并使用内部的“a”:public static final String MYVAL; { MYVAL = "a"; }
    • @BJHargrave: valueOf 委托给toString 实际上将返回相同的实习实例。在创建数字常量时,我​​使用valueOf 保持一致,如Integer.valueOf(1)
    • 是的,但是 valueOf 是必须执行的方法,而 = "a" 是对常量池中字符串的赋值。
    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 2023-03-14
    • 2010-11-13
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 2011-11-07
    相关资源
    最近更新 更多