有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java最终成员在声明中分配的常量是否在运行时优化为“静态最终”?

当我在Java代码中定义常量值时,我通常将它们声明为“private static final”,但最近我一直在维护代码,其中常量定义为“private final”

我现在正在优化,想知道是否要“静态”化这些

比如

public class X {
    private final String SOME_CONST = "Whatever";
}

上述代码(在运行时)是否等同于以下代码,因此只保存了“SOME_CONST”的一个副本

public class X {
    private static final String SOME_CONST = "Whatever";
}

我本以为这是相当基本的,但我在任何地方都找不到答案

[编辑] 一些人回答了被拘留的字符串实例。对不起,我应该选择一个更好的例子,在我所看到的例子中,不仅仅是字符串,还有很多不同的类型(一些是标准的,一些是用户定义的)

我更感兴趣的是“私人决赛”与“私人静态决赛”声明的效果


共 (4) 个答案

  1. # 1 楼答案

    FindBugs有益地指出,这样一个最终成员应该是静态的。可以由此推断,优化没有发生

  2. # 2 楼答案

    SOME_CONST被声明为非静态时,虚拟机将创建一个String实例,其内容为"Whatever"。但是,X类的所有实例都将包含对这个String对象的引用。因此,您的String只有一个实例,但有许多引用

    为了避免不必要的引用,将该字段设置为静态可能是值得的

  3. # 3 楼答案

    没有。在这两种情况下,只有一个String"Whatever"实例,因为所有String文本都被占用

    当字段为static时,从X.class对象只对String实例有一个引用。然而,在非static字段的情况下,每个对象将包含对String实例的不同引用

    换句话说,将字段设为非static将导致每个对象的恒定引用开销(~32位或64位)

  4. # 4 楼答案

    最终字符串在编译时内联使用。所以如果你写

    final String a="A";
    void foo(){ System.out.println(a):}
    

    编译器编写

    final String a="A";
    void foo(){ System.out.println("A"):}
    

    然而,据我所知,编译器并没有将其作为静态代码编写——您仍然可以在每个实例中声明引用