String est une classe VIP. " "est déjà une chaîne!
johnchen902
2
Aucune signification particulière. Je voulais simplement dire très important. Autrement dit, java.lang.Stringayez un traitement spécial du langage Java.
johnchen902
16
Qui a dit que cette chaîne est "une classe comme les autres"? C'est une classe très spéciale, pas comme les autres. Puisque votre supposition est fausse, la question ne peut pas vraiment répondre.
Eric Lippert
5
Ce n'est pas parce que la supposition est fausse que cela ne signifie pas que la question ne peut pas répondre. Et la bonne réponse a déjà 197 voix.
Les concepteurs de Java ont décidé de conserver les types primitifs dans un langage orienté objet, au lieu de faire de tout un objet, afin d'améliorer les performances du langage. Les primitives sont stockées dans la pile d'appels, qui nécessitent moins d'espaces de stockage et sont moins coûteuses à manipuler. D'autre part, les objets sont stockés dans le tas de programme, ce qui nécessite une gestion de la mémoire complexe et plus d'espaces de stockage.
Pour des raisons de performances, la chaîne Java est conçue pour se situer entre une primitive et une classe.
Remarque: les littéraux de chaîne sont stockés dans un pool commun. Cela facilite le partage du stockage pour les chaînes avec le même contenu pour économiser le stockage. Stringles objets alloués via un nouvel opérateur sont stockés dans le heap, et il n'y a pas de partage de stockage pour le même contenu.
Notez que le "pool commun" fait généralement partie du tas.
Joachim Sauer
3
@JoachimSauer Oui..avec peu d'avantages :) a ajouté cela en note.Merci de vous en souvenir.
Suresh Atta
2
Est-il donc plus rapide d'écrire String s1 = "Hello"; que String s2 = new String ("Hello") ;?
user2097804
28
J'ajouterais que dans votre exemple s1 == s2 == s3 mais s4! = S5
Alfredo Osorio
8
@AndrewJanke sur le hotspot récent jvm (7), le pool de chaînes n'est pas en perm gen et à partir de Java 8, il n'y a plus de perm gen ...
assylias
50
Java traite String comme une classe spéciale, vous pouvez l'initialiser des deux manières
Attribuer directement un littéral
String a ="adsasdf";
Comme d'autres objets utilisant un nouveau mot-clé
String a =newString("adsasdf");
Vous devez faire particulièrement attention lorsque vous souhaitez comparer avec le ==signe:
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
C'est parce que dans le premier cas, les objets a et b sont conservés dans quelque chose appelé literal poolet ils font tous les deux référence au même objet, ils sont donc égaux dans les deux sens.
Mais dans le second cas, a et b font référence à différents objets, comme lorsque nous initialisons d'autres objets. ils sont donc inégaux par rapport à l' ==opérateur alors qu'ils sont égaux en valeurs.
La chaîne reçoit un traitement spécial dans le JLS: c'est l'un des deux types non primitifs pour lesquels des littéraux existent (l'autre est Class) * .
Je n'étais pas non plus au courant que le "type nul" est un type approprié en Java. Ses informations très utiles, vous devriez augmenter la taille de la police.
Grijesh Chauhan
1
@GrijeshChauhan: eh bien, le "type nul" est juste une formulation astucieuse pour permettre à n'importe lequel nulld'être affecté à n'importe quelle variable de type référence. Ce n'est pas un type intéressant, sinon.
Joachim Sauer
15
C'est une fonctionnalité du langage Java. Les chaînes littérales du code source reçoivent un traitement spécial.
La spécification du langage, ici , indique simplement qu'une chaîne littérale est de Stringtype
Les chaînes sont très souvent utilisées dans un langage de programmation. Puisque java est orienté objet, une chaîne est un objet. Pour éviter la nouvelle chaîne lourde ("someString"); chaque fois que vous avez besoin d'un objet string java vous permet de créer simplement un objet string en utilisant le littéral string.
Mais vous devez garder à l'esprit l'égalité des chaînes. Voici un court test JUnit pour démontrer ce que je veux dire.
@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());}
Si vous ne pouviez initialiser une chaîne qu'avec new String(String src), vous ne pourriez même pas donner au constructeur un littéral de chaîne. Vous devrez initialiser a char [], puis utiliser le String(char [] src)consructeur pour construire la chaîne, ou vous devrez lire la chaîne à partir d'un fichier.
AJMansfield
Ce n'est pas correct. Un littéral de chaîne n'est qu'une séquence de caractères dans un fichier source entouré de guillemets doubles. Java crée automatiquement une instance d'une chaîne à l'aide de ce littéral. Par conséquent, un littéral et un objet String sont égaux, mais ils ne sont pas identiques. Java pourrait également avoir été implémenté de cette manière que vous devez utiliser la nouvelle chaîne (""); pour instancier un objet String, mais cela ne ferait que rendre notre vie plus difficile. Ainsi, lorsque vous écrivez une nouvelle chaîne ("une chaîne"), java crée un objet String pour le littéral "une chaîne" et transmet cet objet chaîne au constructeur de la nouvelle chaîne.
René Link
2
Juste pour mentionner. Un littéral de chaîne est une référence à une instance de la classe String, vous pouvez écrire du code comme ceci:
- String est une classe en Java . Vous avez raison, nous pouvons donc toujours initialiser avec le newmot - clé.
- Mais quand on fait quelque chose comme:
String s = "";
L'instruction ci-dessus est marquée par le compilateur comme étant un objet String spécial , puis JVM pendant le chargement de la classe (le chargement est effectué avant l'initialisation), voit cela ce que l'on appelle un littéral de chaîne , qui est stocké dans un pool de littéraux de chaîne .
- Ainsi, une chaîne peut être créée en utilisant new()et par la ""méthode, mais cette dernière fournit un littéral de chaîne qui reste dans le tas même s'il n'y a pas de référence à cet objet de chaîne, car il a une référence du pool de littéraux de chaîne.
Le processus que vous décrivez n'est pas ce que fait réellement Java: comme d'autres l'ont déjà indiqué, "hello"est une chaîne littérale et sera placée dans le pool de constantes par le compilateur, voir JLS §3.10.5 et JVMS §5.1 .
siegi
1
Java.lang.Stringn'est pas qu'une classe. Cela fait partie intégrante du langage de base. Le compilateur a du sucre syntaxique pour cela. Par exemple, ""est comme une abréviation pour new String(""). Lorsqu'il est écrit, ""le compilateur optimise des chaînes identiques sur la même instance pour économiser de l'espace."a" + 5 == "a5" ==> true
Le compilateur a du sucre syntaxique pour beaucoup de choses, y compris ne pas avoir à boxer / déballer entre les versions d'objet et leurs types natifs, pas de parent signifie Object, constructeur par défaut, ...
""n'est pas une abréviation pour new String(""). Si vous utilisez "", la première chose à faire est de rechercher des correspondances dans le pool de chaînes de la JVM et si c'est vrai, elle renverra cette chaîne. En utilisant new String(""), vous créerez toujours une nouvelle chaîne, même si la chaîne elle-même existe déjà dans le pool de chaînes (car elle ne sera pas stockée dans le pool de chaînes).
g00glen00b
J'ai mis à jour ma réponse. Les gens utilisent-ils cela à leur avantage, comme utiliser des constantes de chaîne comme un équivalent du type de symbole Lisp?
" "
est déjà une chaîne!java.lang.String
ayez un traitement spécial du langage Java.Réponses:
La chaîne Java est spéciale
Par exemple
Remarque: les littéraux de chaîne sont stockés dans un pool commun. Cela facilite le partage du stockage pour les chaînes avec le même contenu pour économiser le stockage.
String
les objets alloués via un nouvel opérateur sont stockés dans leheap
, et il n'y a pas de partage de stockage pour le même contenu.la source
Java traite String comme une classe spéciale, vous pouvez l'initialiser des deux manières
Attribuer directement un littéral
Comme d'autres objets utilisant un nouveau mot-clé
Vous devez faire particulièrement attention lorsque vous souhaitez comparer avec le
==
signe:C'est parce que dans le premier cas, les objets a et b sont conservés dans quelque chose appelé
literal pool
et ils font tous les deux référence au même objet, ils sont donc égaux dans les deux sens.Mais dans le second cas, a et b font référence à différents objets, comme lorsque nous initialisons d'autres objets. ils sont donc inégaux par rapport à l'
==
opérateur alors qu'ils sont égaux en valeurs.la source
La chaîne reçoit un traitement spécial dans le JLS: c'est l'un des deux types non primitifs pour lesquels des littéraux existent (l'autre est
Class
) * .Depuis le JLS :
* Eh bien, il y a aussi le "type nul" avec son "littéral nul"
null
, mais la plupart des gens ne considèrent pas le "type nul" comme un type approprié.la source
null
d'être affecté à n'importe quelle variable de type référence. Ce n'est pas un type intéressant, sinon.C'est une fonctionnalité du langage Java. Les chaînes littérales du code source reçoivent un traitement spécial.
La spécification du langage, ici , indique simplement qu'une chaîne littérale est de
String
typela source
Le texte entre guillemets doubles crée un
String
objet littéral .Le code ci-dessus crée un
String
objet, en utilisant des guillemets doubles.la source
Les chaînes sont très souvent utilisées dans un langage de programmation. Puisque java est orienté objet, une chaîne est un objet. Pour éviter la nouvelle chaîne lourde ("someString"); chaque fois que vous avez besoin d'un objet string java vous permet de créer simplement un objet string en utilisant le littéral string.
Mais vous devez garder à l'esprit l'égalité des chaînes. Voici un court test JUnit pour démontrer ce que je veux dire.
la source
new String(String src)
, vous ne pourriez même pas donner au constructeur un littéral de chaîne. Vous devrez initialiser achar []
, puis utiliser leString(char [] src)
consructeur pour construire la chaîne, ou vous devrez lire la chaîne à partir d'un fichier.Juste pour mentionner. Un littéral de chaîne est une référence à une instance de la classe String, vous pouvez écrire du code comme ceci:
la source
- String est une classe en Java . Vous avez raison, nous pouvons donc toujours initialiser avec le
new
mot - clé.- Mais quand on fait quelque chose comme:
String s = "";
L'instruction ci-dessus est marquée par le compilateur comme étant un objet String spécial , puis JVM pendant le chargement de la classe (le chargement est effectué avant l'initialisation), voit cela ce que l'on appelle un littéral de chaîne , qui est stocké dans un pool de littéraux de chaîne .
- Ainsi, une chaîne peut être créée en utilisant
new()
et par la""
méthode, mais cette dernière fournit un littéral de chaîne qui reste dans le tas même s'il n'y a pas de référence à cet objet de chaîne, car il a une référence du pool de littéraux de chaîne.la source
Java effectue un processus en deux étapes pour nous.
est équivalent à
Comme [.NET] [1] a une chose similaire.
Est-ce que
Ajout de références: -
la source
"hello"
est une chaîne littérale et sera placée dans le pool de constantes par le compilateur, voir JLS §3.10.5 et JVMS §5.1 .Java.lang.String
n'est pas qu'une classe. Cela fait partie intégrante du langage de base. Le compilateur a du sucre syntaxique pour cela. Par exemple,""
est comme une abréviation pournew String("")
. Lorsqu'il est écrit,""
le compilateur optimise des chaînes identiques sur la même instance pour économiser de l'espace."a" + 5 == "a5" ==> true
Le compilateur a du sucre syntaxique pour beaucoup de choses, y compris ne pas avoir à boxer / déballer entre les versions d'objet et leurs types natifs, pas de parent signifie Object, constructeur par défaut, ...
la source
""
n'est pas une abréviation pournew String("")
. Si vous utilisez""
, la première chose à faire est de rechercher des correspondances dans le pool de chaînes de la JVM et si c'est vrai, elle renverra cette chaîne. En utilisantnew String("")
, vous créerez toujours une nouvelle chaîne, même si la chaîne elle-même existe déjà dans le pool de chaînes (car elle ne sera pas stockée dans le pool de chaînes).