Chaîne de caractères littérales et objet String
Les spécifications de Java expliquent que les chaînes de caractères littérales sont une suite vide ou de plusieurs caractères entre guillemets. Ceci correspond donc au type String. Par conséquent le langage Java permet de créer des chaînes de caractères de deux manières différentes :
// Initialisation de la chaîne de caractères // par la construction de l'objet String String foo = new String("Hello World foo"); // Initialisation de le chaîne de caractères // par affectation d'une chaîne de caractères littérale String bar = "Hello World bar";
On peut se demander si le compilation de ce code donne le même code intermédiaire (bytecode) ou pas.
Le compilation du code pour la construction de l’objet String donne le bytecode suivant :
// Nouvel objet String et référence de cette objet sur la pile NEW java/lang/String // Duplique la référence sur le haut de la pile DUP // Pousse "Hello World foo" depuis le pool de // constantes des Strings sur la pile LDC "Hello World foo" // Invoque la méthode d'initialisation pour construire la String // avec la référence de l'objet et la chaîne de caractères INVOKESPECIAL java/lang/String.(Ljava/lang/String;)V // Stocke la référence de l'objet String // depuis la pile dans une variable locale ASTORE 1
C’est le code intermédiaire normal pour la création d’un objet de type String.
La compilation de l’initialisation d’une chaîne de caractères littérales donne une autre suite d’instructions à ma grande surprise :
// Pousse "Hello World foo" depuis le pool de // constantes des Strings sur la pile LDC "Hello World bar" // Stocke la référence de "Hello World foo" // depuis la pile dans une variable locale ASTORE 1
La grosse différence est que l’initialisation ne passe pas par la construction d’un objet String mais se contente de copier une référence de la chaîne de caractères dans une variable locale ! Du coup, cela économise le temps de construction d’un type String et trois instructions.
Qu’en est il des performances ?
Le test de performance est fait sur la [CONFIG_ARM926EJ-S] avec JamVM 1.5.4 / GnuClasspath 0.98 / Java 1.3. Le code de test permet d’initialiser en boucle les chaînes de caractères suivant les deux méthodes.
| Nombre d'appel | String foo = new String("foo") | String bar = "bar" |
|---|---|---|
| 1 | 6ms | 1ms |
| 10 | 11ms | 7ms |
| 50 | 46ms | 19ms |
| 100 | 48ms | 35ms |
Les tests confirment que l’initialisation d’un objet String via son constructeur est moins performante qu’avec une chaîne de caractères littérales. Suivant les projets et les contraintes de l’embarqué, cela peut améliorer les performances de votre application.

envoi en cours...