2012-08-08 7 views
12

Viele Klassen im Paket javax.sql verwenden den Konstruktor new String(str). Zum Beispiel:Warum verwenden Klassen im Paket 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(""); 
} 

Oder

public void setUsername(String name) { 
    if(name == null) 
    { 
     username = null; 
    } else { 
     username = new String(name); 
    } 
} 

Und vieles mehr:

javax.sql.rowset.serial.SerialStruct.SerialStruct (SQLData, Karte>) javax.sql. rowset.serial.SerialStruct.SerialStruct (Struktur, Map>) javax.sql.rowset.RowSetMetaDataImpl.setCatalogName (int, Zeichenfolge) 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 (String) javax.sql.rowset. BaseRowSet.setDataSourceName (String) java.text.DateFormatSymbols.setLocalPatternChars (String) javax.sql.rowset.BaseRowSet.setNull (int, int, String)

Was ist der Zweck davon? Werden nicht unnötige String-Instanzen auf dem Heap erstellt?

+1

Nach welcher JDK-Implementierung? OpenJDK? – oldrinb

+1

JDK6, Oracle .... Ich habe gerade JDK7 überprüft, und es ist dort behoben – Bozho

+0

In der Tat, ich sehe keine davon in [OpenJDK 7] (http://grepcode.com/file_/repository.grepcode.com /java/root/jdk/openjdk/7-b147/javax/sql/rowset/RowSetMetaDataImpl.java). – oldrinb

Antwort

6

Es scheint, der Code wurde von JDK6 zu JDK7 geändert und alle Instanzen von new String(str) wurden entfernt. Also, obwohl Jon Skeets Vorschlag ziemlich interessant ist, war es wahrscheinlich ein lahmes Stück Code, das sie gefunden und repariert haben.

9

Sie sind möglicherweise gegen den „kleinen Teil eines großen Zeichenfolge“ Schutz Problem:

String x = getHugeStringFromSomewhere(); 
String y = x.substring(0, 5); 
foo(y); 

Nehmen wir nun an die Zeichenfolge bezeichnet durch y erforderlich bleibt, aber x nicht. Da sich y auf das Original char[] bezieht, endet die kleine Zeichenfolge, die für viel Speicher verantwortlich ist.

Wenn Sie eine neue Zeichenfolge stattdessen erstellen, das Kopieren der Daten:

String x = getHugeStringFromSomewhere(); 
String y = new String(x.substring(0, 5)); 
foo(y); 

... dann der darunter liegende große char-Array mit der ursprünglichen Zeichenfolge zugeordnet ist, kann Müll in der gleichen Zeit wie die Zeichenfolge gesammelt werden.

Ich habe gesehen, dass dies einen großen Unterschied macht, wenn man viele kleine Zeilen aus einer großen Textdatei (z. B. Wörter in einem Wörterbuch) liest. IIRC, BufferedReader.readLine erstellt einen Puffer von 80 Zeichen, so dass jeder String Pins mindestens 80 Zeichen char[] zurückgegeben, auch wenn es nur 5 Zeichen lang ist. Es summiert sich ... (Stand Kommentare anscheinend dies in Java 1.5 für readLine geändert - aber substring funktioniert immer noch die gleiche Art und Weise.)

EDIT: Natürlich, die eine Vermutung über den Grund nach wie vor nur ist, und es erklärt auf keinen Fall den new String("") Teil ...

+0

Danke, Teilstring funktioniert so, das ist etwas, das man beachten sollte. Der fragliche Code wurde in JDK7 entfernt, also war es wahrscheinlich nur ein lahmes Stück Code, das sie entdeckten und reparierten :) – Bozho

+0

Auch wenn dies nicht der eigentliche Grund ist, Es ist immer noch eine großartige Sache, über das Gedächtnis nachzudenken und darüber nachzudenken. +1 – Bozho

+0

'neue Zeichenfolge (" ")' ??/Die Implementierung von StringBuffer/String wurde in 1.5 (vor acht Jahren) geändert und kopiert jetzt immer das Backing-Zeichen []. readLine verwendet nur StringBuffer, wenn eine Linie einen Puffer kreuzt (Standard 8192 Zeichen). –

Verwandte Themen