给出以下代码段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(年轻一代?),因为它有本地范围?
答案 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是有利的,允许您为整个类(或包,甚至)定义一次字符串。如果你必须在它使用的任何地方改变它,你只需要改变那个定义。