简体   繁体   English

关于Java中静态字符串与看似本地字符串的寿命

[英]On the longevity of static strings vs seemingly local strings in Java

Given the following snippet A 给出以下代码段A

private static final String SQL = "SELECT * FROM TABLE WHERE ID = ?";

and snippet B 和片段B

public List<MyObject> getData(final Long id){
    return (List<MyObject>)template.query("SELECT * FROM TABLE WHERE ID = ?",id);
}

and snippet C 和摘要C

public List<MyObject> getData(final Long id){
    return (List<MyObject>)template.query(SQL,id);
}

Are B and C effectively the same? B和C有效地相同吗? Does my string in B get gc'd (young generation?) because it has local scope? 我在B中的字符串是否具有gc'd(年轻的一代?),因为它具有局部范围?

String constants are always interned . 字符串常量总是被interned Every time you call snippet B it will use the same string object. 每次调用代码段B时,它将使用相同的字符串对象。 Basically it's equivalent to snippet A+C. 基本上,这相当于代码段A + C。

Indeed, two string constants which have the same sequence of characters will use references to the same string too: 实际上,具有相同字符序列的两个字符串常量也将使用对同一字符串的引用:

String x = "a" + "b";
String y = "ab";

System.out.println(x == y); // true

No. Neither B nor C create a String . 不,B和C都不会创建String The String will be created when the code is loaded (if it does not already exist as an interned String ). 加载代码时将创建String (如果它尚不存在作为内部String )。 It will be garbage collected along with the rest of the code (unless there is another reference to the same String instance). 它将与其余代码一起被垃圾回收(除非有另一个对同一String实例的引用)。

Both B and C use the same string value, since all strings are essentially "cached" by the JVM. B和C都使用相同的字符串值,因为所有字符串实际上都是由JVM“缓存”的。 They exist in memory as long as they need to. 只要需要,它们就存在于内存中。

Whether to use B or C is a matter of code readability (and maintainability). 是否使用B或C是代码可读性(和可维护性)的问题。 Approach B offers the advantage that the SQL query string is immediately adjacent to the code that uses its results, so there should be no question as to what the query is at the point it's being used. 方法B的优势在于,SQL查询字符串紧邻使用其结果的代码,因此,在使用查询时应该毫无疑问。

Approach C is advantageous if you're using the same SQL query string in many places, allowing you to define the string once for the whole class (or package, even). 如果您在许多地方使用相同的SQL查询字符串,则方法C很有用,它允许您为整个类(甚至包)定义一次字符串。 If you ever have to change it everywhere it's used, you only need to change that one definition. 如果必须在使用它的任何地方进行更改,则只需更改一个定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM