Ответ 1
Кажется, код был изменен с JDK6 на JDK7, и все экземпляры new String(str)
были удалены. Итак, хотя предложение Jon Skeet довольно интересно, это, вероятно, был хромой фрагмент кода, который они нашли и исправили.
Многие классы в пакете 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.BaseRowSet.setCommand(String) javax.sql.rowset.BaseRowSet.setDataSourceName(String) java.text.DateFormatSymbols.setLocalPatternChars(String) javax.sql.rowset.BaseRowSet.setNull(int, int, String)
Какова цель этого? Разве это не создает ненужные экземпляры строк в куче?
Кажется, код был изменен с JDK6 на JDK7, и все экземпляры new String(str)
были удалены. Итак, хотя предложение Jon Skeet довольно интересно, это, вероятно, был хромой фрагмент кода, который они нашли и исправили.
Они потенциально защищают от проблемы "маленькой части большой строки":
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);
... тогда основной массив char, связанный с исходной строкой, может быть собран в мусор в то же время, что и строка.
Я видел, что это имеет огромное значение при чтении большого количества крошечных строк из большого текстового файла (например, слова в словаре). IIRC, BufferedReader.readLine
создает буфер из 80 символов, поэтому каждая строка возвращает контакты не менее 80 символов char[]
, даже если это всего лишь 5 символов. Все это добавляет... (Согласно комментариям, по-видимому, это изменилось в Java 1.5 для readLine
- но substring
по-прежнему работает одинаково.)
EDIT: Конечно, это все еще только предположение относительно причины, и это определенно не объясняет часть new String("")
...