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

Java 使用相同的字符串文字而不是最终变量有什么好处?,java,string,final,Java,String,Final,我遇到了一个类,它包含字符串文字“foo”的多种用法 我想知道的是,使用这种方法,而不是将字符串声明为final并用final变量替换所有文本,有什么好处和影响(在对象创建、内存使用和速度方面) 例如(虽然显然不是真正的词语用法): private static final String final\u String=“foo”; 公共打印机(){ 对于(int i=0;i而言,它们将完全相同。在这两种情况下,文本都是内部的(导致该字符串与所有其他常量/文本共享同一实例的任何编译时常量表达式),

我遇到了一个类,它包含字符串文字“foo”的多种用法

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

例如(虽然显然不是真正的词语用法):

private static final String final\u String=“foo”;
公共打印机(){

对于(int i=0;i而言,它们将完全相同。在这两种情况下,文本都是内部的(导致该字符串与所有其他常量/文本共享同一实例的任何编译时常量表达式),智能编译器+运行时应该能够将这两种情况简化为最优化的示例

优点在于可维护性。如果您想更改文字,只需使用常量更改一个实例,但如果每个实例都包含在内联中,则需要搜索并更改它们。


String类型的编译时常量总是“interned”,以便使用String.intern方法共享唯一实例

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


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

这些字符串文字被内部化,因此不会在循环中创建新的字符串对象。不过,使用相同的文字两次可能仍然是代码气味的标志;但在速度或内存使用方面则不然。

在您提供的情况下,我相信将其声明为
FINAL\u STRING
的最大原因是确保它位于一个集中的位置。该字符串常量只有一个实例,但第一个示例更易于维护。

所有字符串文本都保存在字符串缓存中(这是跨所有类的)


如果同一字符串出现在多个地方,使用常量可以使代码更清晰,为字符串提供一些上下文,并使代码更易于维护。

优点不在于性能,而在于可维护性和可靠性

让我举一个我最近遇到的真实例子。一个程序员创建了一个函数,该函数使用一个字符串参数来标识事务的类型。然后在程序中,他将字符串与该类型进行比较。例如:

if (type.equals("stock"))
{ ... do whatever ... }
然后他调用这个函数,将值传递给它“Stock”

你注意到大写字母的区别了吗?最初的程序员也没有注意到。这被证明是一个相当微妙的错误,因为即使查看两个列表,大写字母的差异也没有打动我

相反,如果他声明了一个最终静态,比如

final static String stock="stock";
然后,当他第一次尝试传入“Stock”而不是“Stock”时,他会得到一个编译时错误

在本例中,更好的做法是创建一个枚举,但我们假设他实际上必须将字符串写入输出文件或其他文件,因此它必须是一个字符串

使用最终静力学至少有x个优点:

(1) 如果拼写错误,则会出现编译时错误,而不是可能细微的运行时错误

(2) 静态变量可以为值指定一个有意义的名称。更容易理解的是:

if (employeeType.equals("R")) ...


(三)当存在多个相关值时,您可以将一组最终静态放在程序的顶部,从而告知未来的读者所有可能的值是什么。我已经有很多次看到函数将一个值与两个或三个文本进行比较。这让我想知道:是否还有其他可能的值,或者它?(最好还是有一个枚举,但那是另一回事。)

我不认为之前的开发人员选择使用常量来重复文本,这看起来像是懒惰。奇怪的是,他们实际上声明了常量,但没有使用它。因此我对可能的原因感兴趣。但我同意,我认为这只是懒惰。
if (type.equals("stock"))
{ ... do whatever ... }
final static String stock="stock";
if (employeeType.equals("R")) ...
if (employeeType.equals(EmployeeType.RETIRED)) ...