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

时间:2009-10-07 18:35:43

标签: java string

给出以下代码段A

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

和摘录B

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

和摘录C

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

B和C有效吗? B中的字符串是否得到gc'd(年轻一代?),因为它有本地范围?

3 个答案:

答案 0 :(得分:2)

字符串常量始终是 interned 。每次调用代码段B时,它都将使用相同的字符串对象。基本上它相当于片段A + C.

实际上,具有相同字符序列的两个字符串常量也将使用对同一字符串的引用:

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

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

答案 1 :(得分:1)

没有。 B和C都不会创建String。加载代码时将创建String(如果它不作为实体String存在)。它将与其余代码一起进行垃圾回收(除非有另一个对同一String实例的引用)。

答案 2 :(得分:1)

B和C都使用相同的字符串值,因为JVM基本上“缓存”了所有字符串。只要他们需要,它们就存在于记忆中。

是否使用B或C是代码可读性(和可维护性)的问题。方法B提供的优点是SQL查询字符串与使用其结果的代码紧邻,因此在使用它时,应该毫无疑问查询是什么。

如果您在许多地方使用相同的SQL查询字符串,则方法C是有利的,允许您为整个类(或包,甚至)定义一次字符串。如果你必须在它使用的任何地方改变它,你只需要改变那个定义。