javax.sql包中的许多类都使用new String(str)
构造函数。例如:
public void setCatalogName(int columnIndex, String catalogName) throws SQLException {
checkColRange(columnIndex);
if (catalogName != null)
colInfo[columnIndex].catName = new String(catalogName);
else
colInfo[columnIndex].catName = new String("");
}
或
public void setUsername(String name) {
if(name == null)
{
username = null;
} else {
username = new String(name);
}
}
还有更多:
javax.sql.rowset.serial.SerialStruct.SerialStruct(SQLData,Map>) javax.sql.rowset.serial.SerialStruct.SerialStruct(Struct,Map>) javax.sql.rowset.RowSetMetaDataImpl.setCatalogName(int,String) javax.sql.rowset.RowSetMetaDataImpl.setColumnLabel(int,String) javax.sql.rowset.RowSetMetaDataImpl.setColumnName(int,String) javax.sql.rowset.RowSetMetaDataImpl.setColumnTypeName(int,String) javax.sql.rowset.BaseRowSet.setCommand(字符串) javax.sql.rowset.BaseRowSet.setDataSourceName(字符串) java.text.DateFormatSymbols.setLocalPatternChars(字符串) javax.sql.rowset.BaseRowSet.setNull(int,int,String)
这是为了什么目的?是不是在堆上创建了不必要的字符串实例?
答案 0 :(得分:9)
他们可能会防范“大字符串”的一小部分问题:
String x = getHugeStringFromSomewhere();
String y = x.substring(0, 5);
foo(y);
现在假设y
引用的字符串仍然是必需的,但x
没有。因为y
指的是原始的char[]
,所以你最终会得到那个负责大量内存的小字符串。
如果您创建新字符串,则复制数据:
String x = getHugeStringFromSomewhere();
String y = new String(x.substring(0, 5));
foo(y);
...然后与原始字符串关联的基础大字符数组可以与字符串同时进行垃圾收集。
我已经看到,当从大文本文件(例如字典中的单词)中读取大量细线时,这会产生巨大的差异。 IIRC,BufferedReader.readLine
创建一个80个字符的缓冲区,因此每个字符串返回的引脚至少有80个字符char[]
,即使它只有5个字符长。这一切加起来......(根据评论,显然这在{1.5} for readLine
中发生了变化 - 但substring
仍然以相同的方式工作。)
编辑:当然,这仍然只是猜测原因,它绝对不能解释new String("")
部分...
答案 1 :(得分:6)
似乎代码已从JDK6更改为JDK7,并删除了new String(str)
的所有实例。因此,虽然Jon Skeet的建议非常有趣,但它可能是他们发现并修复的一段蹩脚代码。