Nous créons normalement des objets en utilisant le new
mot - clé, comme:
Object obj = new Object();
Les chaînes sont des objets, mais nous ne les utilisons pas new
pour les créer:
String str = "Hello World";
Pourquoi est-ce? Puis-je créer une chaîne avec new
?
java
string
core
new-operator
giri
la source
la source
new String(...)
a été utilisé pour contourner un détail d'implémentation lors de la sous-chaîne de chaînes volumineuses. Cela a été corrigé dans Java 7 et n'est plus nécessaire.Réponses:
En plus de ce qui a déjà été dit, les chaînes littérales [c'est-à-dire, les chaînes comme
"abcd"
mais pas commenew String("abcd")
] en Java sont internées - cela signifie que chaque fois que vous faites référence à "abcd", vous obtenez une référence à une seuleString
instance, plutôt qu'à une nouvelle chaque fois. Vous aurez donc:mais si tu avais
alors il est possible d'avoir
(et au cas où quelqu'un aurait besoin d'un rappel, utilisez toujours
.equals()
pour comparer les chaînes;==
teste l'égalité physique).L'intégration de littéraux String est une bonne chose car ils sont souvent utilisés plus d'une fois. Par exemple, considérez le code (artificiel):
Si nous n'avions pas d'internement des chaînes, la "prochaine itération" devrait être instanciée 10 fois, alors que maintenant elle ne sera instanciée qu'une seule fois.
la source
Les chaînes sont des objets "spéciaux" en Java. Les concepteurs Java ont judicieusement décidé que les chaînes sont utilisées si souvent qu'ils avaient besoin de leur propre syntaxe ainsi que d'une stratégie de mise en cache. Lorsque vous déclarez une chaîne en disant:
myString est une référence à un objet String avec une valeur de "quelque chose". Si vous déclarez plus tard:
Java est suffisamment intelligent pour déterminer que myString et myOtherString sont identiques et les stockera dans une table de chaînes globale en tant que même objet. Cela repose sur le fait que vous ne pouvez pas modifier les chaînes pour ce faire. Cela réduit la quantité de mémoire requise et peut accélérer les comparaisons.
Si, à la place, vous écrivez
Java créera pour vous un tout nouvel objet, distinct de l'objet myString.
la source
J'espère que cela dissipe quelques doutes. :)
la source
C'est un raccourci. Ce n'était pas comme ça à l'origine, mais Java l'a changé.
Cette FAQ en parle brièvement. Le guide de spécification Java en parle également. Mais je ne peux pas le trouver en ligne.
la source
La chaîne est soumise à quelques optimisations (faute d'une meilleure phrase). Notez que String a également une surcharge d'opérateur (pour l'opérateur +) - contrairement à d'autres objets. C'est donc un cas très spécial.
la source
Nous utilisons généralement des littéraux String pour éviter de créer des objets inutiles. Si nous utilisons un nouvel opérateur pour créer un objet String, il créera un nouvel objet à chaque fois.
Exemple:
Pour le code ci-dessus en mémoire:
la source
En Java, les chaînes sont un cas particulier, avec de nombreuses règles qui ne s'appliquent qu'aux chaînes. Les guillemets doubles obligent le compilateur à créer un objet String. Étant donné que les objets String sont immuables, cela permet au compilateur d'interner plusieurs chaînes et de créer un pool de chaînes plus grand. Deux constantes String identiques auront toujours la même référence d'objet. Si vous ne voulez pas que ce soit le cas, vous pouvez utiliser le nouveau String (""), et cela créera un objet String au moment de l'exécution. La méthode intern () était autrefois courante, pour que les chaînes créées dynamiquement soient vérifiées par rapport à la table de recherche de chaînes. Une fois qu'une chaîne est internée, la référence d'objet pointe vers l'instance de chaîne canonique.
Lorsque le chargeur de classe charge une classe, toutes les constantes String sont ajoutées au pool String.
la source
Sucre syntaxique. le
la syntaxe est toujours disponible.
la source
String small = new String(huge.substring(int, int));
, qui vous permet de recycler le gros sous-jacent àchar[]
partir de lahuge
chaîne d' origine .Vous pouvez toujours utiliser
new String("string")
, mais il serait plus difficile de créer de nouvelles chaînes sans littéraux de chaîne ... vous devrez utiliser des tableaux de caractères ou des octets :-) Les littéraux de chaîne ont une propriété supplémentaire: tous les mêmes littéraux de chaîne de n'importe quelle classe pointent vers la même chaîne instance (ils sont internés).la source
Il n'est presque pas nécessaire de créer une nouvelle chaîne car le littéral (les caractères entre guillemets) est déjà un objet String créé lorsque la classe hôte est chargée. Il est parfaitement légal d'invoquer des méthodes sur un littéral et don, la principale distinction est la commodité fournie par les littéraux. Ce serait une douleur et un gaspillage majeurs si nous devions créer un tableau de caractères et le remplir char par char et faire un nouveau String (char array).
la source
N'hésitez pas à créer une nouvelle chaîne avec
La notation habituelle
s = "new String";
est plus ou moins un raccourci pratique - qui devrait être utilisé pour des raisons de performances, sauf dans les cas assez rares, où vous avez vraiment besoin de chaînes qui se qualifient pour l'équationÉDITER
En réponse au commentaire: il ne s'agissait pas d'un conseil, mais simplement d'une réponse directe à la thèse des questionneurs, à savoir que nous n'utilisons pas le mot-clé «nouveau» pour les chaînes, ce qui n'est tout simplement pas vrai. J'espère que cette modification (y compris celle ci-dessus) clarifie un peu cela. BTW - il y a quelques bonnes et bien meilleures réponses à la question ci-dessus sur SO.
la source
new String(...)
MOINS QUE votre application ne vous oblige à créer une chaîne avec une identité distincte.Le pool littéral contient toutes les chaînes créées sans utiliser le mot clé
new
.Il y a une différence: la chaîne sans nouvelle référence est stockée dans le pool littéral de chaîne et la chaîne avec new indique qu'elles sont dans la mémoire du tas.
Les chaînes avec new sont ailleurs en mémoire, comme n'importe quel autre objet.
la source
Parce que String est une classe immuable dans java.
Maintenant, pourquoi est-il immuable? Comme String est immuable, il peut être partagé entre plusieurs threads et nous n'avons pas besoin de synchroniser l'opération String en externe. As String est également utilisé dans le mécanisme de chargement de classe. Donc, si String était mutable, java.io.writer aurait pu être changé en abc.xyz.mywriter
la source
Production:
J'ai créé deux objets séparés, tous deux ont un champ (ref) 'Nom'. Donc même dans ce cas "Jan Peter" est partagé, si je comprends bien la façon dont java traite ..
la source
Eh bien, le StringPool est implémenté en utilisant The Hashmap en java. Si nous créons toujours avec un nouveau mot-clé, il ne recherche pas dans le pool de chaînes et ne crée pas une nouvelle mémoire pour celui-ci, ce qui pourrait être nécessaire plus tard si une opération gourmande en mémoire est en cours d'exécution et si nous créons toutes les chaînes avec un nouveau mot-clé qui affecterait les performances de notre application. Il est donc conseillé de ne pas utiliser de nouveaux mots-clés pour créer une chaîne, car alors seulement il ira au pool de chaînes qui à son tour est un Hashmap, (mémoire enregistrée, imaginez si nous avons beaucoup de chaînes créées avec un nouveau mot-clé) ici, il sera stocké et si la chaîne existe déjà, sa référence (qui résiderait généralement dans la mémoire de la pile) serait renvoyée à la chaîne nouvellement créée. C'est donc fait pour améliorer les performances.
la source