使用相同的字符串文本而不是最终变量有什么好处?

2022-09-01 05:45:52

我遇到过一个类,其中包含字符串文字“foo”的多种用法。

我想知道的是,使用这种方法而不是将字符串声明为最终值并将所有文本替换为最终变量的好处和影响(在对象创建,内存使用和速度方面)是什么?

例如(尽管显然不是真正的单词用法):

private static final String FINAL_STRING = "foo";

public void stringPrinter(){
    for(int i=0;i<10;i++){
        System.out.println(FINAL_STRING);
    }
}

对:

public void stringPrinter(){
    for(int i=0;i<10;i++){
        System.out.println("foo");
    }
}

哪个更可取,为什么(假设字符串值将保持不变)?

上面的(第二个)示例是否会导致创建 10 个 String 对象,或者 JVM 是否会意识到实际上只使用了一个文本,并创建单个引用。如果是这样,将字符串声明为 final(如第一个示例中所示)是否有任何好处?

如果解释的代码确实将字符串文本替换为单个引用,则当同一文本出现在多个位置时,这是否仍然适用:

public void stringPrinter(){
    for(int i=0;i<5;i++){
        System.out.println("foo"); // first occurence
        System.out.println("foo"); // second occurence
    }
}

答案 1

它们将完全相同。在这两种情况下,文本都是暂存的(导致该字符串的任何编译时常量表达式与所有其他常量/文本共享相同的实例),智能编译器+运行时应该可以毫无困难地将两者简化为最优化的示例。

优势更多地体现在可维护性上。如果要更改文本,则只需使用常量更改一个匹配项,但需要搜索并更改每个实例(如果它们以内联方式包含在内)。


答案 2

从JLS
编译时常量开始,String类型的编译时常量总是“暂存”,以便使用String.intern方法共享唯一的实例。

所以,不,将只有一个字符串对象。

正如Mark所指出的,这完全是可维护性的问题,而不是性能问题。