Je travaille sur un projet où toutes les conversions de int
à String
se font comme suit:
int i = 5;
String strI = "" + i;
Je ne suis pas familier avec Java. Est-ce une pratique habituelle ou quelque chose ne va pas, comme je suppose?
Les manières normales seraient Integer.toString(i)
ou String.valueOf(i)
.
La concaténation fonctionnera, mais elle n’est pas conventionnelle et pourrait être une mauvaise odeur, car elle suggère que l’auteur ne connaît pas les deux méthodes ci-dessus (que peuvent-ils ne pas savoir d'autre?).
Java supporte spécialement l'opérateur + lorsqu'il est utilisé avec des chaînes (voir la documentation ) qui traduit le code que vous avez publié en:
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(i);
String strI = sb.toString();
au moment de la compilation. C'est légèrement moins efficace (sb.append()
finit par appeler Integer.getChars()
, ce que Integer.toString()
aurait fait de toute façon), mais cela fonctionne.
Pour répondre au commentaire de Grodriguez: ** Non, le compilateur n'optimise pas l'optimisation de la chaîne vide dans ce cas - regardez:
simon@lucifer:~$ cat TestClass.Java
public class TestClass {
public static void main(String[] args) {
int i = 5;
String strI = "" + i;
}
}
simon@lucifer:~$ javac TestClass.Java && javap -c TestClass
Compiled from "TestClass.Java"
public class TestClass extends Java.lang.Object{
public TestClass();
Code:
0: aload_0
1: invokespecial #1; //Method Java/lang/Object."<init>":()V
4: return
public static void main(Java.lang.String[]);
Code:
0: iconst_5
1: istore_1
Initialisez le StringBuilder:
2: new #2; //class Java/lang/StringBuilder
5: dup
6: invokespecial #3; //Method Java/lang/StringBuilder."<init>":()V
Ajouter la chaîne vide:
9: ldc #4; //String
11: invokevirtual #5; //Method Java/lang/StringBuilder.append:
(Ljava/lang/String;)Ljava/lang/StringBuilder;
Ajouter l'entier:
14: iload_1
15: invokevirtual #6; //Method Java/lang/StringBuilder.append:
(I)Ljava/lang/StringBuilder;
Extraire la dernière chaîne:
18: invokevirtual #7; //Method Java/lang/StringBuilder.toString:
()Ljava/lang/String;
21: astore_2
22: return
}
Il y a ne proposition et le travail en cours pour changer ce comportement, ciblé pour JDK 9.
C'est acceptable, mais je n'ai jamais rien écrit de tel. Je préférerais ceci:
String strI = Integer.toString(i);
Ce n'est pas un bon moyen.
Lors de la conversion de int en chaîne, ceci devrait être utilisé:
int i = 5;
String strI = String.valueOf(i);
Ce n'est pas seulement l'optimisation1. Je n'aime pas
"" + i
parce qu'il n'exprime pas ce que je veux vraiment faire 2.
Je ne veux pas ajouter un entier à une chaîne (vide). Je veux convertir un entier en chaîne:
Integer.toString(i)
Ou, pas mon préféré, mais toujours mieux que la concaténation, obtenir une représentation sous forme de chaîne d'un objet (entier):
String.valueOf(i)
1. Pour le code appelé très souvent, comme dans les boucles, l'optimisation est également un point pour ne pas utiliser la concaténation.
2. ceci n'est pas valable pour une utilisation de real concaténation comme dansSystem.out.println("Index: " + i);
oString id = "ID" + i;
Beaucoup de cours d'introduction à l'université semblent enseigner ce style, pour deux raisons (d'après mon expérience):
Cela ne nécessite pas de compréhension des classes ou des méthodes. Habituellement, cela est enseigné bien avant que le mot "classe" ne soit jamais mentionné - ni même les appels de méthodes. Donc, utiliser quelque chose comme String.valueOf(…)
pourrait semer la confusion chez les étudiants.
C'est une illustration de la "surcharge d'opérateur" - en fait, cela nous a été vendu comme le opérateur surchargé idiomatique (petite merveille ici, puisque Java n'autorise pas la surcharge personnalisée de l'opérateur ).
Cela peut donc naître de la nécessité didactique (même si j’arguais que c’est un mauvais enseignement) ou être utilisé pour illustrer un principe qui est par ailleurs assez difficile à démontrer en Java.
L'expression
"" + i
conduit à la conversion de chaîne de i
au moment de l'exécution. Le type général de l'expression est String
. i
est d'abord converti en un objet Integer
(new Integer(i)
), puis String.valueOf(Object obj)
est appelé. Donc, cela équivaut à
"" + String.valueOf(new Integer(i));
Évidemment, ceci est légèrement moins performant que le simple appel de String.valueOf(new Integer(i))
qui produira le même résultat.
L'avantage de ""+i
est que la frappe est plus facile/plus rapide et certaines personnes peuvent penser que c'est plus facile à lire. Ce n'est pas un odeur de code car cela n'indique aucun problème plus profond.
(Référence: JLS 15.8.1 )
Personnellement, je ne vois rien de mal dans ce code.
C'est très utile lorsque vous souhaitez enregistrer une valeur int et que l'enregistreur accepte uniquement une chaîne. Je dirais qu'une telle conversion est pratique lorsque vous devez appeler une méthode acceptant une chaîne, mais que vous avez une valeur int.
Quant au choix entre Integer.toString
ou String.valueOf
, tout est une question de goût.
... Et en interne, le String.valueOf
appelle la méthode Integer.toString
au passage. :)
L’autre moyen dont j’ai connaissance est celui de la classe Integer
:
Integer.toString(int n);
Integer.toString(int n, int radix);
Un exemple concret (bien que je ne pense pas que vous en ayez besoin):
String five = Integer.toString(5); // returns "5"
Cela fonctionne aussi pour d'autres types primitifs, par exemple Double.toString
.
Cette technique a été enseignée dans un cours d'initiation au langage Java de premier cycle que j'ai suivi il y a une décennie. Toutefois, je dois noter que, IIRC, nous n’avions pas encore eu recours aux méthodes de classe String et Integer.
La technique est simple et rapide à taper. Si tout ce que je fais est d’imprimer quelque chose, je l’utiliserai (par exemple, System.out.println("" + i);
. Cependant, je pense que ce n’est pas la meilleure façon de faire une conversion, car il faut une seconde de réflexion pour comprendre ce qui se passe. En outre, si la performance est une préoccupation, il semble plus lent (plus bas, ainsi que dans d'autres réponses).
Personnellement, je préfère Integer.toString (), car ce qui se passe est évident. String.valueOf () serait mon deuxième choix, car il semble être source de confusion (voyez les commentaires après la réponse de darioo).
Juste pour les sourires :) J'ai écrit des cours pour tester les trois techniques: "" + i, Integer.toString et String.ValueOf. Chaque test vient de convertir les entiers de 1 à 10 000 en chaînes. J'ai ensuite exécuté chacune des commandes Linux time cinq fois. Integer.toString () était légèrement plus rapide que String.valueOf () une fois, ils ont fait l'égalité trois fois, et String.valueOf () était plus rapide une fois; Cependant, la différence ne dépassait jamais quelques millisecondes.
La technique "" + i était plus lente que les deux tests sur tous les tests sauf un, alors qu'elle était 1 milliseconde plus rapide que Integer.toString () et 1 milliseconde plus lente que String.valueOf () (évidemment sur le même test où String.valueOf () était plus rapide que Integer.toString ()). Alors qu’il était généralement plus lent de quelques millisecondes, il y avait un test où il était d’environ 50 millisecondes plus lent. YMMV .
Il existe différentes manières de convertir en chaînes:
StringBuilder string = string.append(i).toString();
String string = String.valueOf(i);
String string = Integer.toString(i);
Cela dépend de la façon dont vous voulez utiliser votre chaîne. Cela peut aider:
String total = Integer.toString(123) + Double.toString(456.789);
Il existe de nombreuses façons de convertir un entier en chaîne:
1)
Integer.toString(10);
2)
String hundred = String.valueOf(100); // You can pass an int constant
int ten = 10;
String ten = String.valueOf(ten)
3)
String thousand = "" + 1000; // String concatenation
4)
String million = String.format("%d", 1000000)
String strI = String.valueOf(i);
String string = Integer.toString(i);
Les deux manières sont correctes.
Il y a trois façons de convertir en chaînes
String string = "" + i;
String string = String.valueOf(i);
String string = Integer.toString(i);
Ditto surtout sur SimonJ. Je n'aime vraiment pas le "" + idiome. Si vous dites String.valueOf (i), Java convertit l'entier en chaîne et renvoie le résultat. Si vous dites "" + i, Java crée un objet StringBuilder, y ajoute une chaîne vide, convertit l'entier en chaîne, l'ajoute au StringBuilder, puis convertit StringBuilder en chaîne. Cela fait beaucoup d'étapes supplémentaires. Je suppose que si vous le faites une fois dans un grand programme, ce n'est pas grave. Mais si vous le faites tout le temps, vous forcez l'ordinateur à faire beaucoup de travail supplémentaire et à créer tous ces objets supplémentaires qui doivent ensuite être nettoyés. Je ne veux pas devenir fanatique de la micro-optimisation, mais je ne veux pas non plus perdre inutilement de l'argent.
Utiliser "" + i est le moyen le plus court et le plus simple de convertir un nombre en chaîne. Ce n'est pas le plus efficace, mais c'est le plus clair des IMHO et c'est généralement le plus important. Plus le code est simple, moins vous risquez de vous tromper.
Personnellement, je pense que "" + j’ai vraiment l’air que l’affiche originale de la question dit "puante". J'ai utilisé beaucoup de OO langages autres que Java. Si cette syntaxe était censée être appropriée, alors Java interpréterait simplement le i seul sans que le "" souhaité soit converti en chaîne et le ferait, car le type de destination est non ambigu et que seule une valeur unique être fourni à droite. L’autre semble être un "truc" pour tromper le compilateur, mauvais mojo quand différentes versions de Javac faites par d’autres fabricants ou par d’autres plates-formes sont considérées si le code doit jamais être porté. Heck pour mon argent, il devrait plaire à de nombreux autres OOL prenez un transtypage de caractères: (String) i. winks
Compte tenu de ma manière d'apprendre et de la facilité de compréhension d'une telle construction lorsque je lis rapidement du code, je vote pour la méthode Integer.toString (i). Oublier un ou deux dans la façon dont Java implémente les choses en arrière-plan par rapport à String.valueOf (i), cette méthode me convient parfaitement et dit exactement ce qui se passe: I have et Integer et je souhaite qu'elle soit convertie en un string.
Un bon point soulevé à quelques reprises est peut-être que simplement utiliser StringBuilder à l’avance est une bonne réponse pour construire des chaînes composées de texte et d’ints ou d’autres objets puisque c’est ce qui sera utilisé en arrière-plan de toute façon, non?
Juste mes deux sous jeté dans le minou déjà bien payé des réponses à la question du Mans ... sourit
modifier ma propre réponse après quelques réflexions:
Ok, ok, j'y pensais un peu plus et String.valueOf (i) est également parfaitement bon. Il dit également: je veux une chaîne qui représente la valeur d'un Integer. lol, l'anglais est de loin plus difficile à analyser que Java! Mais, je laisse le reste de ma réponse/mon commentaire ... On m'a toujours appris à utiliser le plus bas niveau d'une chaîne de méthodes/fonctions, si possible, tout en maintenant la lisibilité. Par conséquent, si String.valueOf appelle Integer.toString, alors pourquoi utiliser tout un orange si tu vas juste le peler de toute façon, Hmmm?
Pour clarifier mon commentaire à propos de StringBuilder, je construis beaucoup de chaînes avec des combinaisons de texte essentiellement littéral et int, et elles finissent par être longues et laides avec des appels aux routines susmentionnées imbriquées entre les +, donc il me semble que celles-ci deviennent De toute façon, les objets SB et la méthode append ayant des surcharges, il pourrait être plus propre de simplement l'utiliser et de l'utiliser ... Donc, je suppose que je suis à 5 cents sur celui-ci maintenant, hein? lol ...