是否有可能禁用javac对静态final变量的内联?

12 浏览
0 Comments

是否有可能禁用javac对静态final变量的内联?

Java静态编译器(javac)会内联一些静态final变量,并将其值直接带入常量池。考虑以下示例。类A定义了一些常量(公共静态final变量):

public class A {
    public static final int INT_VALUE = 1000;
    public static final String STRING_VALUE = "foo";
}

类B使用了这些常量:

public class B {
    public static void main(String[] args) {
        int i = A.INT_VALUE;
        System.out.println(i);
        String s = A.STRING_VALUE;
        System.out.println(s);
    }
}

当编译类B时,javac从类A获取这些常量的值,并将这些值内联到B.class中。因此,在编译时,B对类A的依赖关系从字节码中被擦除。这是一个非常特殊的行为,因为您在编译时就在常量中固化了这些常量的值。您可能会认为这是JIT编译器在运行时可以轻松完成的最简单的事情之一。

是否有任何方法或任何隐藏的编译器选项可以禁用javac的内联行为?背景是,我们正在进行字节码分析以进行依赖性分析,并且这是少数几种字节码分析无法检测到编译时依赖性的情况之一。谢谢!

编辑:这是一个令人烦恼的问题,因为通常我们无法控制所有的源代码(例如,定义常量的第三方库)。我们对从使用常量的角度检测这些依赖性感兴趣。由于引用从使用常量的代码中被擦除,所以没有简单的方法来检测它们,除非进行源代码分析。

0