88 votes

Cordes de Java: "String s = new String("idiot");"

Je suis une C++ gars de l'apprentissage de Java. Je suis en train de lire Efficace Java et quelque chose me troublait. Il est dit de ne jamais écrire le code comme ceci:

String s = new String("silly");

Parce qu'il crée inutilement des objets String. Mais au lieu de cela, il devrait être écrit comme ceci:

String s = "No longer silly";

Ok bien loin...Cependant, compte tenu de cette classe:

public final class CaseInsensitiveString{
    private String s;
    public CaseInsensitiveString(String s){
    	if (s == null) {
    		throw new NullPointerException();
        }
    	this.s = s;
    }
    :
    :
}

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
  1. Pourquoi est la première instruction ok? Ne devrait-elle pas être

    CaseInsensitiveString cis = "polonais";

  2. Comment puis-je faire CaseInsensitiveString se comportent comme des Cordes de façon à ce que la déclaration ci-dessus est ok (avec et sans extension de Chaîne)? Quel est-il de Chaîne de fait, il est ok pour simplement être en mesure de passer un littéral comme ça? De ma compréhension, il n'existe pas de constructeur de copie" concept en Java droit?

115voto

Adam Rosenfield Points 176408

String est un spécial intégré dans la classe de la langue. Il est pour l' String classe uniquement dans lequel vous devez éviter de le dire

String s = new String("Polish");

Parce que le littéral "Polish" est déjà de type String, et vous êtes en train de créer un inutile à l'objet. Pour toute autre classe, en disant:

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");

est la bonne (et seulement dans ce cas) une chose à faire.

58voto

Leigh Points 2144

Je crois que le principal avantage de l'utilisation de la forme littérale (c'est à dire, "foo", plutôt que de new String("toto")), c'est que tous les littéraux de Chaîne sont des "internés" par la machine virtuelle. En d'autres termes, il est ajouté à un pool de telle sorte que tout autre code qui crée la même chaîne va utiliser la mise en commun de la Chaîne plutôt que de créer une nouvelle instance.

À titre d'exemple, le code suivant va imprimer vrai pour la première ligne, mais faux pour la seconde:

System.out.println("foo" == "foo");
System.out.println(new String("bar") == new String("bar"));

30voto

Steve B. Points 23227

Les chaînes de caractères sont traités un peu spécialement en java, ils sont immuables, de sorte qu'il est sûr pour eux d'être manipulés par de comptage de référence.

Si vous écrivez

String s = "Polish";
String t = "Polish";

ensuite, s et t en fait référence à un même objet, et s==t renverra true, "= = " pour les objets de lecture "est le même objet" (ou peut, de toute façon, je ne suis pas sûr si c'est la partie de la langue spec ou tout simplement un détail de l'implémentation de compilateur-alors peut-être il n'est pas sûr de s'appuyer sur cette) .

Si vous écrivez

String s = new String("Polish");
String t = new String("Polish");

alors s!=t (parce que vous avez explicitement créé une nouvelle chaîne de caractères) même si l'article.est égal à(t) retourne vrai (car la chaîne ajoute ce comportement est égal).

La chose que vous voulez écrire,

CaseInsensitiveString cis = "Polish";

ne peut pas travailler parce que vous êtes en train de penser que les citations sont une sorte de court-circuit du constructeur de votre objet, alors qu'en fait, cela ne fonctionne que pour plain old java.lang.Les chaînes de caractères.

20voto

String s1="foo"; littéral vont aller dans la piscine et s1 fera référence.

String s2="foo"; cette fois, il coche la case "foo" littérale est déjà disponible dans StringPool ou pas comme aujourd'hui il existe donc s2 renverra le même littéral.

String s3=new String("toto"); "foo" littérale sera créé dans StringPool d'abord, puis à travers string arg Chaîne du constructeur d'Objet sera créé-je.e "foo" dans le tas en raison de la création d'un objet par le biais de nouvelles opérateur s3 de le soumettre.

Chaîne s4=new String("toto"); le même que s3

si le Système..println(s1==s2);// true en raison littérale de comparaison.

et le Système..println(s3==s4);// false en raison de l'objet comparaison(s3 et s4 est créé à différents endroits dans le tas)

12voto

Alnitak Points 143355

Strings ont la particularité de Java - ils sont immuables, et des constantes de chaîne sont automatiquement transformées en String objets.

Il n'y a aucun moyen pour votre SomeStringClass cis = "value" exemple de s'appliquer à toute autre classe.

Ni étendre String, parce qu'il est déclaré comme final, ce qui signifie pas de sous-classement est autorisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X