Strings erzeugen

Generic1

Top Contributor
Hi,

ich hab gerade Effective Java gelesen und da steht drinnen, man soll:

String s = "test";

anstatt

String s = new String("test");

schreiben.
Macht das bei den heutigen Java Compiler eigentlich noch einen Unterschied? oder wird das im hintergrund alles zu einem StringBuilder?

Besten Dank!
 
T

Tomate_Salat

Gast
Es ist nicht das gleiche:
Java:
public static void main(final String[] args) 
{
	String test1="test";
	String test2="test";
	String test3=new String("test");
	
	System.out.println(test1==test2);
	System.out.println(test1==test3);
}

Ergibt:
Code:
true
false

test1 und test2 referenzieren das gleiche Objekt. test1 und test3 nicht. Man soll eben die Variante hier nehmen:
Java:
String stringValue="value";

Weil der String aus einem Pool genommen wird, wenn schon vorhanden. Es wird also nicht immer explizit ein neuer erstellt.
 

fidibus

Mitglied
Hallo,

meines wissens nach ist der Datentyp String ein Referenztyp in Java, dass heißt kein einfacher Datentyp. Und somit ist es eigentlich egal welche Schreibweise du verwendenest. bei der Schreibweise new wird der Konstruktor eben expliziet von dir aufgerufen und bei der anderen Schreibweise wird der Konstruktor implizit augerufen.

Grüße
 

tfa

Top Contributor
bei der Schreibweise new wird der Konstruktor eben expliziet von dir aufgerufen und bei der anderen Schreibweise wird der Konstruktor implizit augerufen.
Bei der zweiten Variante werden 2 Strings erzeugt. Einer davon wird gleich wieder weggeworfen, nachdem der Inhalt in den zweiten String kopiert worden ist. Das ist nutzlos und überflüssig. Deswegen ist dieser String(String)-Konstruktor praktisch ebenfalls nutzlos.
 
B

bygones

Gast
Hallo,

meines wissens nach ist der Datentyp String ein Referenztyp in Java, dass heißt kein einfacher Datentyp. Und somit ist es eigentlich egal welche Schreibweise du verwendenest. bei der Schreibweise new wird der Konstruktor eben expliziet von dir aufgerufen und bei der anderen Schreibweise wird der Konstruktor implizit augerufen.

Grüße

Strings bilden nochmals eine Sondergruppe, da sie, wie gesagt, aus einem Pool genommen werden, wenn man sie nicht selbst explizit konstruiert.

Ebenso sollte man immer die valueOf methoden von Integer etc nehmen, da diese ebenso gecached werden (jdf ein Teil), sowie Boolean.TRUE u. Boolean.FALSE nehmen - anstatt selbst immer welche zu erzeugen.
 

fidibus

Mitglied
Hallo,

Zitat: fidibus

Beitrag anzeigen



Hallo,

meines wissens nach ist der Datentyp String ein Referenztyp in Java, dass heißt kein einfacher Datentyp. Und somit ist es eigentlich egal welche Schreibweise du verwendenest. bei der Schreibweise new wird der Konstruktor eben expliziet von dir aufgerufen und bei der anderen Schreibweise wird der Konstruktor implizit augerufen.

Grüße


Strings bilden nochmals eine Sondergruppe, da sie, wie gesagt, aus einem Pool genommen werden, wenn man sie nicht selbst explizit konstruiert.

Ebenso sollte man immer die valueOf methoden von Integer etc nehmen, da diese ebenso gecached werden (jdf ein Teil), sowie Boolean.TRUE u. Boolean.FALSE nehmen - anstatt selbst immer welche zu erzeugen.

Diesbezüglich liegt der Fehler natürlich auf meiner Seite. Aber danke für die Korrektur.:) Man lernt halt nie aus.
Grüße
 

fastjack

Top Contributor
@tfa Bleibt bei
Java:
new String("lala")
nicht einer auf dem Heap zurück, bis die GC zuschlägt und ihn "eventuell" abräumt? Ich weis das man damit nämlich wunderschöne Memory Leaks produzieren kann...
 

PollerJava

Top Contributor
werden bei

Java:
String s = new String("test");

jetzt 2 Strings erzeugt oder einer und wie kann man das beweisen?
 

pl4gu33

Top Contributor
werden bei

Java:
String s = new String("test");

jetzt 2 Strings erzeugt oder einer und wie kann man das beweisen?

hier wird ein neuer String erzeugt, der nicht aus dem Pool genommen wird.

schau dir mal "Tomate_Salat"'s Beispiel an, dann siehst du auch direkt den Beweis, dass es 2 unterschiedliche Strings sind wenn man sie mit "==" "vergleicht"
 

PollerJava

Top Contributor
hier wird ein neuer String erzeugt, der nicht aus dem Pool genommen wird.

schau dir mal "Tomate_Salat"'s Beispiel an, dann siehst du auch direkt den Beweis, dass es 2 unterschiedliche Strings sind wenn man sie mit "==" "vergleicht"

Bitte genau lesen wenn du schon antworten willst.
Meine Frage war ob mit der Zeile

String s = new String("test");

zwei Strings erzeugt werden -> also new String("test"); und dieses Objekt/dieser String dann in ein neues Objekt kopiert wird oder ob nur ein Objekt erzeugt wird und s auf dieses Objekt zeigt?
 
B

...ButAlive

Gast
Ja
Code:
String test = new String("test");
erzeugt zwei String-Objekte. Wobei "test" eine Konstante ist, und im Constantpool der Classfile "lebt".
Code:
new String(String)
ist der Copy-Konstruktor von String, dieser erzeugt eine tiefe Kopie des internen char-Arrays, des übergebenen Strings und verbraucht damit doppelt soviel Speicher als
Code:
String test = "test";
.

Wobei ich mich frage, wieso String einen Copy-Konstruktor braucht, diese sind eigentlich bei Immutablen überflüssig.
 
S

Spacerat

Gast
Also zum Literal mit Doublequotes ("string")... Um solche Dinge kümmert sich der GC erst, wenn er die gesammte Klasse ensorgen kann, wo sie definiert wurden, den dort ist auch der Stringpool (eigentlich ConstantPool) zu finden.
[OOPS]Letzten Beitrag übersehen...[/OOPS].
Aber erzeugt wird durch new halt nur einer, der andere ist Teil der Klasse. Die DeepCopy wird nur gemacht, wenn originalValue.length > original.count ist, ein Umstand, der bei Literalen kaum passieren kann.
Java:
    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
	int size = original.count;
	char[] originalValue = original.value;
	char[] v;
  	if (originalValue.length > size) {
 	    // The array representing the String is bigger than the new
 	    // String itself.  Perhaps this constructor is being called
 	    // in order to trim the baggage, so make a copy of the array.
            int off = original.offset;
            v = Arrays.copyOfRange(originalValue, off, off+size);
 	} else {
 	    // The array representing the String is the same
 	    // size as the String, so no point in making a copy.
	    v = originalValue;
 	}
	this.offset = 0;
	this.count = size;
	this.value = v;
    }
 
Zuletzt bearbeitet von einem Moderator:

fastjack

Top Contributor
Ich denke richtig ist aber, das dabei zwei String-Objekte entstehen und darum ging es im ganzen Thread.

Java:
public String(String original) {
....
}

Was macht ein Konstruktor? Richtig, ein Konstruktor erzeugt ein neues Objekt ;) Was hier geshared, bzw. kopiert wird, ist das zugrunde liegende char[], aber nicht das String-Objekt selbst, darum hast Du am Ende 2 String-Objekte..
 
S

Spacerat

Gast
Das's doch nur wieder die halbe Wahrheit (nämlich nur der erste Teil), darum geht's ja in diesem Thread. Die Frage ist doch, warum man das eine dem anderen vorziehen soll.
Natürlich erzeugt "new" immer ein Objekt aber das kannst du von mir aus auch "n" mal machen, sowohl erneut auf das Literal als auch auf seine Kinder und Kindeskinder. Auf diese Art erzeugte Stringobjekte verhunzen in diesem Fall immer 16 Bytes des wertvollen Heaps. Literale (Text in den Ganterpranken) werden nicht durch "new" erzeugt, sondern durch die JVM, welche den Text (das Chararray) aus dem Constantpool der Klasse bezieht. Durch [c]"new String("literal")[/c] wird die JVM höchstens daran gehindert, die Erzeugerklasse aus dem Speicher zu "entsorgen", wenn sie nicht mehr benötigt wird. Literale kopiert man anders. [c]new StringBuilder("literal").toString()[/c] forciert die oben genannte deepCopy. Die 16 + 2*n Bytes auf dem Heap finden ihre Berechtigung nun darin, ein Literal ausserhalb seiner Erzeugerklasse zu verwenden. So werden evtl. nur Stringlänge + 16 Bytes statt X-Bytes gesamte KlassenDefinition erhalten, aber auch bei diesem Konstrukt gibt's Haken, der Speicherverbrauch bei falscher Anwendung. Dieser String-Copy-Konstruktor aber ist nutzlos, solange die DeepCopy nicht erfolgt (muss ja automatisch erfolgen), was sie bei Literalen halt nicht tut, wohl aber unter Umständen bei Variablen des Typs String.
 
Zuletzt bearbeitet von einem Moderator:

fastjack

Top Contributor
Das stimmt schon, was Du schreibst. Trotzdem wird bei new String("lala") ein String-Objekt erzeugt, welche Du bei String s = "lala" einfach mal nicht hast ;) Was eben gerade die Antwort auf die Frage des TO's ist. Man muß also die 16 Bytes des Heaps nicht "verhunzen".

Die Frage ist doch, warum man das eine dem anderen vorziehen soll.

Verstehe ich nicht, ich würde new String("lala") niemals der anderen Variante vorziehen.

Durch "new String("literal") wird die JVM höchstens daran gehindert, die Erzeugerklasse aus dem Speicher zu "entsorgen", wenn sie nicht mehr benötigt wird.

Tja stell Dir das mal in einer Schleife vor und/oder in einer langlebigen Klasse vor. Dann wird Dein "höchstens" schnell zum Problem.
 

xehpuk

Top Contributor
Da hier der Zweck des Konstruktors noch nicht so wirklich genannt wurde:
Bei einer Methode wie
Code:
substring()
ist der neu erzeugte String nicht komplett "unabhängig" von dem ursprünglichen. Beide referenzieren ab diesem Zeitpunkt dasselbe char-Array. Kommt nun der ursprüngliche String out-of-scope und wird vom GC eingesammelt, bleibt trotzdem dessen char-Array übrig, weil es ja noch vom neuen String referenziert wird. Wenn dieses char-Array um ein Vielfaches größer als der neue String ist und dieser über einen längeren Zeitraum referenziert wird, ist es eine Überlegung wert, eine Kopie zu erzeugen. So wird ein neues char-Array mit der Länge des Strings erstellt. Der alte große "Klumpen" kann dadurch dann auch vom GC eingesammelt werden.
 
S

Spacerat

Gast
Verstehe ich nicht, ich würde new String("lala") niemals der anderen Variante vorziehen.
Eben, ich auch nicht. Soll man ja auch nicht. Gerade so, wie es der TO bei Effective Java gelesen hat.
Tja stell Dir das mal in einer Schleife vor und/oder in einer langlebigen Klasse vor. Dann wird Dein "höchstens" schnell zum Problem.
Ähhh, du meinst eigentlich doch eher sonst kurzlebige Klassen. Das Problem ist doch, dass manche Klassen nur deswegen so langlebig sind, weil irgend so 'n [IRONIE]Kasper einen dort definierten im Zweifelsfalle auch noch einen Leerstring in einer seiner Klassen als Konstante benutzt. Herzlichen Glückwunsch. :lol:[/IRONIE] Wär schön, wenn die VM solche Konstrukte wegoptimieren würde, keine Ahnung, ob sie das macht. Ansonsten werden langlebige Klassen ja eh' mehr oder weniger exessiv benutzt - z.B. String oder ganz oben auf der Liste Object.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
O regulärer Ausdruck zum durchsuchen eines Strings verwenden Allgemeine Java-Themen 2
B HeapSort für Array of Strings funktioniert nur teilweise Allgemeine Java-Themen 3
W JSON parsen eines ,mit JS.stringify erstellten Strings Allgemeine Java-Themen 27
L allgemein Strings händisch in Liste sortieren Allgemeine Java-Themen 47
N MySQL mit Strings Allgemeine Java-Themen 3
T Letztes Zeichen eines Strings enfernen Allgemeine Java-Themen 14
P Strings: equals vs == Allgemeine Java-Themen 47
G Objekte mit Strings Aufrufen Allgemeine Java-Themen 8
W Collections Suche Collection, um Strings mit Indizees versehen Allgemeine Java-Themen 47
V Datentypen Graphikrechner 2/Strings und Variablen in Doubles umwandeln Allgemeine Java-Themen 6
LimDul Mittels Streams aus Strings A B C den String A, B und C machen Allgemeine Java-Themen 12
Meeresgott Best Practice Strings auf Inhalte vergleichen Allgemeine Java-Themen 1
N DNA Strings vergleichen Allgemeine Java-Themen 1
Q-bert Strings aus der JList in eine Datenbank speichern Allgemeine Java-Themen 1
K Vergleich von Strings von Objekten Allgemeine Java-Themen 4
J Strings int textdokumente speicher Allgemeine Java-Themen 3
KeVoZ_ Nacheinander folgende Strings in Textdokument auf neue Zeile schreiben Allgemeine Java-Themen 6
K Strings sortieren: 2 Kritieren Allgemeine Java-Themen 5
A Vector Strings in Array splitten Allgemeine Java-Themen 6
B Wie vergleiche ich Strings in einer Liste? Allgemeine Java-Themen 5
T Strings über Bluetooth zwischen PC,µc oder Samrtphone senden und empfangen Allgemeine Java-Themen 0
N Methoden Methoden einer Klasse auf Grundlage eines Strings aufrufen Allgemeine Java-Themen 6
K Bestimmten Bereich eines Strings lesen Allgemeine Java-Themen 6
H RegularExpression zwischen zwei Strings Allgemeine Java-Themen 2
Neumi5694 Operatoren regEx für das Erstellen eines Strings verwenden Allgemeine Java-Themen 3
H Strings vergleichen Allgemeine Java-Themen 9
O Mustererkennung in Strings Allgemeine Java-Themen 4
Y String-Collection: längste gemeinsame Strings / Prefixe Allgemeine Java-Themen 3
F Problem mit Strings Allgemeine Java-Themen 8
D Strings chemisch splitten Allgemeine Java-Themen 3
K Wörter in Strings zählen Allgemeine Java-Themen 7
L Strings nach sortiertem String zurück ordnen Allgemeine Java-Themen 0
L Strings nach gleichem Muster ordnen Allgemeine Java-Themen 4
L Fragen für Facharbeit: Analyse von Strings in Java Allgemeine Java-Themen 4
D Strings vergleichen; Komma ignorieren Allgemeine Java-Themen 3
K Java Operatoren mit Strings darstellen Allgemeine Java-Themen 8
B HTML Tags in Strings umwandeln Allgemeine Java-Themen 4
N Input/Output Vergleich von identischen Strings schlägt fehl Allgemeine Java-Themen 5
U Große Liste von Strings mit indiziertem Zugriff Allgemeine Java-Themen 31
A ,,Textformatierungsbefehle" für strings deaktivieren Allgemeine Java-Themen 8
S Strings vergleichen Allgemeine Java-Themen 11
C Strings in Excel einlesen! Allgemeine Java-Themen 2
S Strings gehen "kaputt" wenn ich in CVS ein und wieder auschecke. Allgemeine Java-Themen 2
X Datentypen Prozentualer Abgleich zwischen 2 Strings (Pattern?) Allgemeine Java-Themen 3
R MD5-Hash eines Strings bestimmen Allgemeine Java-Themen 2
C Strings und JSON Objekte so klein wie möglich im Speicher ablegen Allgemeine Java-Themen 5
J String zerlegen in einzelne Strings Allgemeine Java-Themen 7
F Konstanten mir Strings "verknuepfen" Allgemeine Java-Themen 10
1 zwei Strings vergleichen Allgemeine Java-Themen 16
L Object Instanz anhand eines Strings Allgemeine Java-Themen 10
S vector & strings Allgemeine Java-Themen 26
N Strings mit null wiedergabe Splitten Allgemeine Java-Themen 4
K Strings sortieren (knifflig) Allgemeine Java-Themen 7
P Codierung der strings umändern Allgemeine Java-Themen 10
N Zahlen in Strings einer ArrayList sortieren Allgemeine Java-Themen 14
F 2 Strings zusammenfügen Allgemeine Java-Themen 2
D Strings von HTML befreien Allgemeine Java-Themen 17
S Strings zu Color-Instanzen parsen? Allgemeine Java-Themen 7
C Strings zwischen 2 Zeichen auslesen Allgemeine Java-Themen 7
T Explizite Typkonversation mit Strings Allgemeine Java-Themen 9
R Locale spezifische DateFormat Strings? Allgemeine Java-Themen 3
M Wie kann ich alle System.out Strings in ein log window umleiten? Allgemeine Java-Themen 6
R Java function die Strings escaped, sodass ich sie in Javascript verwenden kann? Allgemeine Java-Themen 4
ruutaiokwu objektreferenz eines strings... Allgemeine Java-Themen 9
data89 [Kurze Frage] Ähnlichkeit zweier Strings ermitteln Allgemeine Java-Themen 19
S bestimmte Strings spliten! Allgemeine Java-Themen 7
M Warum Strings mit equals vergleichen... Allgemeine Java-Themen 6
Daniel_L Suche nach ganzen Wörtern (wholeword) in Strings? Allgemeine Java-Themen 4
A Strings joinen, Standard-Library? Allgemeine Java-Themen 9
Y Mal wieder vergleichen von Strings.[Leider noch ein Problem] Allgemeine Java-Themen 18
data89 Die Größe eines Strings in Byte berechnen? Allgemeine Java-Themen 12
A Auslesen von Strings aus einer xls-Datei Allgemeine Java-Themen 16
G Spezialfrage zu Strings Allgemeine Java-Themen 11
C Textteile aus Strings extrahieren? Allgemeine Java-Themen 6
J Teile eines Strings ersetzen Allgemeine Java-Themen 2
G schnell Strings vergleichen Allgemeine Java-Themen 4
J Name eines Strings durch einen String festlegbar? Allgemeine Java-Themen 2
G Strings zerlegen und substrings auslesen Allgemeine Java-Themen 2
Z Letztes zeichen eines strings löschen Allgemeine Java-Themen 3
V Speicherplatz eines Strings? Allgemeine Java-Themen 12
H MIDlets und Strings Allgemeine Java-Themen 2
C Pixelanzahl eines Strings ermitteln Allgemeine Java-Themen 12
T Strings darf nur Ziffern, +/- haben Allgemeine Java-Themen 9
A Fehler beim Ersetzen eines Strings Allgemeine Java-Themen 3
G Strings die Zahlen enthalten sinnvoll sortieren (A2 < A10 Allgemeine Java-Themen 4
G byte[] mit Strings füllen Allgemeine Java-Themen 2
H strings in datei verschlüsseln , auslesen mit klartext aber! Allgemeine Java-Themen 2
F Strings in JList ausrichten/links/rechts/mittig Allgemeine Java-Themen 10
M String#equals(), Probleme mit großen Strings? Allgemeine Java-Themen 4
H ein Teil des Strings rausfiltern Allgemeine Java-Themen 8
E Viele if Abfragen auf viele Strings --> Alternative zu if Allgemeine Java-Themen 8
C Strings zu groß um damit zu arbeiten Allgemeine Java-Themen 31
V Lib für Strings suchen und ersetzen (erweitert) Allgemeine Java-Themen 3
P Schnelles Auslesen von Strings für Syntaxhighlighting? Allgemeine Java-Themen 2
X Strings aus einer ArrayList zählen Allgemeine Java-Themen 11
C HASH Algorithmus 2 Strings ergeben das Selbe. Allgemeine Java-Themen 2
G Datei zeilenweise in Strings speichern Allgemeine Java-Themen 36
S Methode zum Zählen von Buchstaben in Strings gesucht Allgemeine Java-Themen 11
I vergleich und zählen von Strings Allgemeine Java-Themen 7
V Strings aus externen Dateien Einlesen (Sudoku) Allgemeine Java-Themen 25

Ähnliche Java Themen

Neue Themen


Oben