java 使用相同的字符串文字而不是最终变量有什么好处?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4830403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the benefits of using identical String literals instead of a final variable?
提问by Michael
I've come across a class that includes multiple uses of a string literal, "foo".
我遇到过一个包含多次使用字符串文字“foo”的类。
What I'd like to know, is what are the benefits and impact (in terms of object creation, memory usage and speed) of using this approach instead of declaring the String as final and replacing all the literals with the final variable?
我想知道的是,使用这种方法而不是将 String 声明为 final 并将所有文字替换为 final 变量有什么好处和影响(在对象创建、内存使用和速度方面)?
For example (although obviously not a real word usage):
例如(虽然显然不是真正的单词用法):
private static final String FINAL_STRING = "foo";
public void stringPrinter(){
for(int i=0;i<10;i++){
System.out.println(FINAL_STRING);
}
}
Versus:
相对:
public void stringPrinter(){
for(int i=0;i<10;i++){
System.out.println("foo");
}
}
Which is preferable and why (assuming the string value will remain constant)?
哪个更可取,为什么(假设字符串值将保持不变)?
Would the above (second) example result in 10 String objects being created or would the JVM realise that only a single literal is actually used, and create a single reference. If so, is there any advantage for declaring the String as final (as in the first example)?
上面(第二个)示例会导致创建 10 个 String 对象,还是 JVM 会意识到实际上只使用了一个文字,并创建了一个引用。如果是这样,将 String 声明为 final 有什么好处(如第一个示例中所示)?
If the interpreted code does replace the string literal with a single reference, does that still apply if the same literal occurs in more than one place:
如果解释的代码确实用单个引用替换了字符串文字,如果相同的文字出现在多个地方,这是否仍然适用:
public void stringPrinter(){
for(int i=0;i<5;i++){
System.out.println("foo"); // first occurence
System.out.println("foo"); // second occurence
}
}
回答by Mark Peters
They will be exactly the same. The literal is interned (any compile time constant expression that results in that string shares the same instance as all other constants/literals) in both cases and a smart compiler+runtime should have no trouble reducing both to the most optimized example.
它们将完全相同。在这两种情况下,字面量都被固定(任何编译时常量表达式导致该字符串与所有其他常量/字面量共享相同的实例),并且智能编译器+运行时应该可以轻松地将两者都简化为最优化的示例。
The advantage comes more in maintainability. If you want to change the literal, you would need only change one occurrence with a constant but you would need to search and change every instance if they were included inline.
优势更多地体现在可维护性上。如果您想更改文字,您只需要使用常量更改一次出现,但如果它们被内联包含,您将需要搜索和更改每个实例。
回答by Nikita Rybak
From the JLS
Compile-time constants of type String are always "interned" so as to share unique instances, using the method String.intern.
来自 JLS
的 String 类型的编译时常量总是使用 String.intern 方法“实习”,以便共享唯一的实例。
So, no, there's gonna be only one string object.
所以,不,只有一个字符串对象。
As Mark notes, this is strictly the question of maintainability and not performance.
正如 Mark 所指出的,这严格来说是可维护性问题,而不是性能问题。
回答by Jay
The advantage is not in performance, but in maintainability and reliability.
优势不在于性能,而在于可维护性和可靠性。
Let me take a real example I came across just recently. A programmer created a function that took a String parameter that identified the type of a transaction. Then in the program he did string compares against this type. Like:
让我举一个我最近遇到的真实例子。一位程序员创建了一个函数,该函数采用一个字符串参数来标识事务的类型。然后在程序中他对这种类型进行了字符串比较。喜欢:
if (type.equals("stock"))
{ ... do whatever ... }
Then he called this function, passing it the value "Stock".
然后他调用这个函数,将值“Stock”传递给它。
Do you notice the difference in capitalization? Neither did the original programmer. It proved to be a fairly subtle bug to figure out, because even looking at both listings, the difference in capitalization didn't strike me.
你注意到大小写的不同了吗?原来的程序员也没有。事实证明这是一个相当微妙的错误,因为即使查看两个列表,我也没有注意到大小写的差异。
If instead he had declared a final static, say
相反,如果他声明了最终静态,请说
final static String stock="stock";
Then the first time he tried to pass in "Stock" instead of "stock", he would have gotten a compile-time error.
然后当他第一次尝试传入“Stock”而不是“stock”时,他会得到一个编译时错误。
Better still in this example would have been to make an enum, but let's assume he actually had to write the string to an output file or something so it had to be a string.
在这个例子中更好的是创建一个枚举,但让我们假设他实际上必须将字符串写入输出文件或其他东西,所以它必须是一个字符串。
Using final statics gives at least x advantages:
使用最终静力学至少有 x 个优势:
(1) If you mis-spell it, you get a compile-time error, rather than a possibly-subtle run-time error.
(1) 如果你拼错了它,你会得到一个编译时错误,而不是一个可能微妙的运行时错误。
(2) A static can assign a meaingful name to a value. Which is more comprehensible:
(2) 静态可以为值分配有意义的名称。哪个更容易理解:
if (employeeType.equals("R")) ...
or
或者
if (employeeType.equals(EmployeeType.RETIRED)) ...
(3) When there are multiple related values, you can put a group of final statics together at the top of the program, thus informing future readers what all the possible values are. I've had plenty of times when I've seen a function compare a value against two or three literals. And that leaves me wondering: Are there other possible values, or is this it? (Better still is often to have an enum, but that's another story.)
(3)当有多个相关值时,可以将一组final statics放在程序顶部,从而告知未来的读者所有可能的值是什么。我曾多次看到一个函数将一个值与两个或三个文字进行比较。这让我想知道:是否还有其他可能的值,或者就是这样?(最好还是经常有一个枚举,但那是另一回事了。)
回答by Peter Lawrey
All String literals are kept in a String cache (this is across all classes)
所有字符串文字都保存在一个字符串缓存中(这是跨所有类)
Using a constant can make the code clearer, give the the string some context and make the code easier to maintain esp if the same string appears in multiple places.
使用常量可以使代码更清晰,为字符串提供一些上下文并使代码更易于维护,尤其是如果相同的字符串出现在多个位置。
回答by Erich Kitzmueller
Those string literals are internalized, so no new String objects are created in the loop. Using the same literal twice could still be a sign for code smell, though; but not in terms of speed or memory usage.
这些字符串文字是内化的,因此循环中不会创建新的 String 对象。但是,两次使用相同的文字仍然可能是代码异味的标志;但不是在速度或内存使用方面。
回答by James
In the cases you are providing, I believe the biggest reason for having it declared as FINAL_STRING
somewhere is to ensure it stays in one centralized location. There will only ever be one instance of that string constant, but the first example is far easier to maintain.
在您提供的情况下,我认为将其声明为FINAL_STRING
某处的最大原因是确保它位于一个集中位置。该字符串常量只会有一个实例,但第一个示例更容易维护。