String ist eine VIP-Klasse. " "ist schon ein String!
Johnchen902
2
Keine besondere Bedeutung. Ich meinte nur sehr wichtig. Das heißt, java.lang.Stringhaben Sie eine spezielle Behandlung der Java-Sprache.
Johnchen902
16
Wer sagt, dass String "eine Klasse wie jede andere" ist? Es ist eine ganz besondere Klasse, wie keine andere. Da Ihre Vermutung falsch ist, ist die Frage nicht wirklich beantwortbar.
Eric Lippert
5
Nur weil die Annahme falsch ist, heißt das nicht, dass die Frage nicht beantwortet werden kann. Und die richtige Antwort hat bereits 197 Stimmen.
Die Entwickler von Java beschlossen, primitive Typen in einer objektorientierten Sprache beizubehalten, anstatt alles zu einem Objekt zu machen, um die Leistung der Sprache zu verbessern. Grundelemente werden im Aufrufstapel gespeichert, die weniger Speicherplatz benötigen und billiger zu manipulieren sind. Andererseits werden Objekte im Programmheap gespeichert, was eine komplexe Speicherverwaltung und mehr Speicherplätze erfordert.
Aus Leistungsgründen ist Javas String so konzipiert, dass er zwischen einem Grundelement und einer Klasse liegt.
Hinweis: String-Literale werden in einem gemeinsamen Pool gespeichert. Dies erleichtert die gemeinsame Nutzung des Speichers für Zeichenfolgen mit demselben Inhalt, um Speicherplatz zu sparen. StringObjekte, die über einen neuen Operator zugewiesen wurden, werden im gespeichert heap, und es gibt keine gemeinsame Nutzung des Speichers für denselben Inhalt.
Beachten Sie, dass der "gemeinsame Pool" normalerweise Teil des Heaps ist.
Joachim Sauer
3
@ JoachimSauer Ja..mit kleinen Vorteilen :) fügte das in Anmerkung hinzu. Danke fürs Erinnern.
Suresh Atta
2
Ist es also schneller, String s1 = "Hello" zu schreiben? als String s2 = neuer String ("Hallo");?
user2097804
28
Ich würde das in Ihrem Beispiel hinzufügen s1 == s2 == s3 aber s4! = S5
Alfredo Osorio
8
@ AndrewJanke auf dem letzten Hotspot JVM (7), der String-Pool ist nicht in Perm Gen und von Java 8 gibt es keine Perm Gen mehr ...
Assylias
50
Java behandelt String als eine spezielle Klasse, die Sie auf beide Arten initialisieren können
Literal direkt zuweisen
String a ="adsasdf";
Wie andere Objekte mit neuem Schlüsselwort
String a =newString("adsasdf");
Sie müssen besonders vorsichtig sein, wenn Sie mit ==Zeichen vergleichen möchten:
String a ="asdf";String b ="asdf";System.out.println(a == b);// TrueSystem.out.println(a.equals(b));// TrueString a =newString("asdf");String b =newString("asdf");System.out.println(a == b);// FalseSystem.out.println(a.equals(b));// True
Dies liegt daran, dass im ersten Fall die Objekte a und b in einem so genannten literal poolObjekt gehalten werden und beide auf dasselbe Objekt verweisen, sodass sie in beiden Richtungen gleich sind.
Im zweiten Fall verweisen a und b jedoch auf unterschiedliche Objekte, beispielsweise wenn wir andere Objekte initialisieren. Daher sind sie im Vergleich zum ==Operator ungleich , während ihre Werte gleich sind.
Mir war auch nicht bewusst, dass "Null-Typ" ein richtiger Typ in Java ist. Es ist eine sehr hilfreiche Information, Sie sollten die Schriftgröße erhöhen.
Grijesh Chauhan
1
@GrijeshChauhan: Nun, der "Null-Typ" ist nur ein geschickter Wortlaut, damit jeder nullbeliebige Referenztyp-Variable zugewiesen werden kann. Sonst ist es kein interessanter Typ.
Joachim Sauer
15
Es ist eine Funktion der Java-Sprache. String-Literale im Quellcode werden besonders behandelt.
Die Sprachspezifikation hier sagt einfach, dass ein String-Literal vom StringTyp ist
Zeichenfolgen werden sehr häufig in einer Programmiersprache verwendet. Da Java objektorientiert ist, ist eine Zeichenfolge ein Objekt. Um den umständlichen neuen String ("someString") zu vermeiden; Anweisung Jedes Mal, wenn Sie ein Zeichenfolgenobjekt benötigen, können Sie mit Java nur ein Zeichenfolgenobjekt mithilfe des Zeichenfolgenliteral erstellen.
Sie sollten jedoch die String-Gleichheit berücksichtigen. Hier ein kurzer JUnit-Test, um zu demonstrieren, was ich meine.
@Testpublicvoid stringTest(){// a string literal and a string object created // with the same literal are equal
assertEquals("string",newString("string"));// two string literals are the same string object
assertSame("string","string");// a string literal is not the same object instance // as a string object created with the same string literal
assertFalse("string"==newString("string"));// java's String.intern() method gives you the same// string object reference for all strings that are equal.
assertSame("string",newString("string").intern());}
Wenn Sie nur einen String mit initialisieren könnten, könnten new String(String src)Sie dem Konstruktor nicht einmal ein String-Literal geben. Sie müssten a initialisieren char []und dann den String(char [] src)Konstruktor verwenden, um die Zeichenfolge zu erstellen, oder Sie müssten die Zeichenfolge aus einer Datei lesen.
AJMansfield
Das ist nicht richtig. Ein String-Literal ist nur eine Zeichenfolge in einer Quelldatei, die durch doppelte Anführungszeichen gekennzeichnet ist. Java erstellt mit diesem Literal automatisch eine Instanz einer Zeichenfolge. Daher sind ein Literal- und ein String-Objekt gleich, aber sie sind nicht gleich. Java hätte auch so implementiert werden können, dass Sie einen neuen String ("") verwenden müssen. ein String-Objekt zu instanziieren, aber dies würde unser Leben nur schwieriger machen. Wenn Sie also einen neuen String ("einen String") schreiben, erstellt Java ein String-Objekt für das Literal "ein String" und übergibt dieses String-Objekt an den Construtor des neuen Strings.
René Link
2
Nur um es zu erwähnen. Ein String-Literal ist ein Verweis auf eine Instanz der Klasse String. Sie können Code wie folgt schreiben:
- String ist eine Klasse in Java . Sie haben Recht damit, sodass wir immer mit dem newSchlüsselwort initialisieren können .
- Aber wenn wir so etwas machen wie:
String s = "";
Die obige Anweisung wird vom Compiler als spezielles String-Objekt markiert, und dann sieht JVM beim Laden der Klasse (das Laden erfolgt vor der Initialisierung) das sogenannte String-Literal , das in einem String-Literal-Pool gespeichert ist .
- Ein String kann also mit new()und mit der ""Methode erstellt werden. Letzterer stellt jedoch ein String-Literal bereit, das auch dann im Heap verbleibt, wenn kein Verweis auf dieses String-Objekt vorhanden ist, da es einen Verweis aus dem String-Literal-Pool enthält.
Der von Ihnen beschriebene Prozess ist nicht das, was Java tatsächlich tut: Wie andere bereits angegeben haben, "hello"handelt es sich um ein Zeichenfolgenliteral, das vom Compiler in den konstanten Pool gestellt wird (siehe JLS §3.10.5 und JVMS §5.1) .
Siegi
1
Java.lang.Stringist nicht nur eine Klasse. Es ist ein wesentlicher Bestandteil der Kernsprache. Der Compiler hat syntaktischen Zucker dafür. Zum Beispiel ""ist wie eine Abkürzung für new String(""). Wenn geschrieben"" optimiert der Compiler identische Zeichenfolgen für dieselbe Instanz, um Platz zu sparen."a" + 5 == "a5" ==> true
Der Compiler verfügt über syntaktischen Zucker für viele Dinge, einschließlich der Tatsache, dass zwischen Objektversionen und ihren nativen Typen kein Box / Unbox erforderlich ist. Kein übergeordnetes Mittel Objekt, Standardkonstruktor, ...
""ist keine Abkürzung für new String(""). Wenn Sie verwenden "", müssen Sie zunächst im String-Pool der JVM nach Übereinstimmungen suchen. Wenn dies zutrifft, wird dieser String zurückgegeben. Mit verwenden new String("")Sie immer einen neuen String, auch wenn der String selbst bereits im String-Pool vorhanden ist (da er nicht im String-Pool gespeichert wird).
g00glen00b
Ich habe meine Antwort aktualisiert. Nutzen die Leute dies zu ihrem Vorteil, wie die Verwendung von String-Konstanten, die dem Lisp-Symboltyp entsprechen?
" "
ist schon ein String!java.lang.String
haben Sie eine spezielle Behandlung der Java-Sprache.Antworten:
Java String ist etwas Besonderes
Beispielsweise
Hinweis: String-Literale werden in einem gemeinsamen Pool gespeichert. Dies erleichtert die gemeinsame Nutzung des Speichers für Zeichenfolgen mit demselben Inhalt, um Speicherplatz zu sparen.
String
Objekte, die über einen neuen Operator zugewiesen wurden, werden im gespeichertheap
, und es gibt keine gemeinsame Nutzung des Speichers für denselben Inhalt.quelle
Java behandelt String als eine spezielle Klasse, die Sie auf beide Arten initialisieren können
Literal direkt zuweisen
Wie andere Objekte mit neuem Schlüsselwort
Sie müssen besonders vorsichtig sein, wenn Sie mit
==
Zeichen vergleichen möchten:Dies liegt daran, dass im ersten Fall die Objekte a und b in einem so genannten
literal pool
Objekt gehalten werden und beide auf dasselbe Objekt verweisen, sodass sie in beiden Richtungen gleich sind.Im zweiten Fall verweisen a und b jedoch auf unterschiedliche Objekte, beispielsweise wenn wir andere Objekte initialisieren. Daher sind sie im Vergleich zum
==
Operator ungleich , während ihre Werte gleich sind.quelle
String wird im JLS besonders behandelt: Es ist einer der beiden nicht-primitiven Typen, für die Literale existieren (der andere ist
Class
) * .Aus dem JLS :
* Nun, es gibt auch den "Null-Typ" mit dem "Null-Literal"
null
, aber die meisten Leute halten den "Null-Typ" nicht für einen richtigen Typ.quelle
null
beliebige Referenztyp-Variable zugewiesen werden kann. Sonst ist es kein interessanter Typ.Es ist eine Funktion der Java-Sprache. String-Literale im Quellcode werden besonders behandelt.
Die Sprachspezifikation hier sagt einfach, dass ein String-Literal vom
String
Typ istquelle
Text in doppelten Anführungszeichen erstellt ein Literalobjekt
String
.Der obige Code erstellt ein
String
Objekt in doppelten Anführungszeichen.quelle
Zeichenfolgen werden sehr häufig in einer Programmiersprache verwendet. Da Java objektorientiert ist, ist eine Zeichenfolge ein Objekt. Um den umständlichen neuen String ("someString") zu vermeiden; Anweisung Jedes Mal, wenn Sie ein Zeichenfolgenobjekt benötigen, können Sie mit Java nur ein Zeichenfolgenobjekt mithilfe des Zeichenfolgenliteral erstellen.
Sie sollten jedoch die String-Gleichheit berücksichtigen. Hier ein kurzer JUnit-Test, um zu demonstrieren, was ich meine.
quelle
new String(String src)
Sie dem Konstruktor nicht einmal ein String-Literal geben. Sie müssten a initialisierenchar []
und dann denString(char [] src)
Konstruktor verwenden, um die Zeichenfolge zu erstellen, oder Sie müssten die Zeichenfolge aus einer Datei lesen.Nur um es zu erwähnen. Ein String-Literal ist ein Verweis auf eine Instanz der Klasse String. Sie können Code wie folgt schreiben:
quelle
- String ist eine Klasse in Java . Sie haben Recht damit, sodass wir immer mit dem
new
Schlüsselwort initialisieren können .- Aber wenn wir so etwas machen wie:
String s = "";
Die obige Anweisung wird vom Compiler als spezielles String-Objekt markiert, und dann sieht JVM beim Laden der Klasse (das Laden erfolgt vor der Initialisierung) das sogenannte String-Literal , das in einem String-Literal-Pool gespeichert ist .
- Ein String kann also mit
new()
und mit der""
Methode erstellt werden. Letzterer stellt jedoch ein String-Literal bereit, das auch dann im Heap verbleibt, wenn kein Verweis auf dieses String-Objekt vorhanden ist, da es einen Verweis aus dem String-Literal-Pool enthält.quelle
Java führt für uns einen zweistufigen Prozess durch.
ist äquivalent zu
Wie [.NET] [1] hat eine ähnliche Sache.
tut
Hinzufügen von Referenzen: -
quelle
"hello"
handelt es sich um ein Zeichenfolgenliteral, das vom Compiler in den konstanten Pool gestellt wird (siehe JLS §3.10.5 und JVMS §5.1) .Java.lang.String
ist nicht nur eine Klasse. Es ist ein wesentlicher Bestandteil der Kernsprache. Der Compiler hat syntaktischen Zucker dafür. Zum Beispiel""
ist wie eine Abkürzung fürnew String("")
. Wenn geschrieben""
optimiert der Compiler identische Zeichenfolgen für dieselbe Instanz, um Platz zu sparen."a" + 5 == "a5" ==> true
Der Compiler verfügt über syntaktischen Zucker für viele Dinge, einschließlich der Tatsache, dass zwischen Objektversionen und ihren nativen Typen kein Box / Unbox erforderlich ist. Kein übergeordnetes Mittel Objekt, Standardkonstruktor, ...
quelle
""
ist keine Abkürzung fürnew String("")
. Wenn Sie verwenden""
, müssen Sie zunächst im String-Pool der JVM nach Übereinstimmungen suchen. Wenn dies zutrifft, wird dieser String zurückgegeben. Mit verwendennew String("")
Sie immer einen neuen String, auch wenn der String selbst bereits im String-Pool vorhanden ist (da er nicht im String-Pool gespeichert wird).