Cabinet de curiosité du JDK n°2 : String.intern

Vous avez certainement souvent utilisé la classe String, néanmoins celle-ci recèle des choses très intéressantes.

Utilisation de l'opérateur ==

Dans le cas où vous vous voulez créer deux Object leurs instances seront forcément différentes:

Object objet1 = new Object()
Object objet2 = new Object();

objet1 == objet2 renvoie toujours false.

Ce qui explique que l'on utilise la méthode equals plutôt que l'identité des références pour la majorité des classes java.

Néanmoins la classe String propose un comportement différent.

Exemple 1
String string1 = "123456789";
String string2 = "123456789";

le résultat de string1 == string2 vaut true.

Exemple 2
String string1 = new String("123456789");
String string2 = new String("123456789");

le résultat de string1 == string2 vaut false.

Exemple 3
String string1 = new String("123456789");
String string2 = new String("123456789");

le résultat de string1.intern() == string2.intern() vaut true.

La méthode intern()

Ainsi lors de la déclaration d'une référence de type String, deux situations se présentent :

• si une valeur littérale y est directement associée, cette dernière sera automatiquement placée dans le pool et la référence de l'objet pointera dessus (déclaration du type String test = "une petite chaine").
• si une nouvelle instance de String est créée, la valeur qu'elle représente ne sera pas mise dans le pool (String test = new String("une petite chaine")), une nouvelle instance de cette chaîne sera donc créée.

Or la méthode intern() renvoie la représentation interne de la chaîne, c'est-à-dire celle qu'elle va placer dans le pool si elle n'y est pas présente ou la récupérer s'y trouve déjà.

String java.lang.String.intern()

Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

Returns: a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

Quel est donc l'intérêt de la méthode intern() ?

Elle permet d'effectuer des optimisations non négligeables en terme de temps d'exécution (ce qui est fait dans certains parsers XML). En effet le temps d'exécution de la méthode equals est beaucoup plus long que l'utilisation de l'opérateur == : equals doit vérifier l'identité de chacun des caractères des deux chaines.

En conclusion, utilisez la méthode intern pour les chaines que vous aurez à manipuler souvent, les chaînes de caractère constantes par exemple.

Attention

- la méthode intern est une méthode native, elle dépend dont de l'implémentation de la JVM.

- seules deux chaînes strictement identiques sont placées à la même adresse dans le pool, et sont donc déclarées identiques par l'opérateur "==",

- il ne faut pas placer toutes les chaînes manipulées par un programme dans le pool de string, cela pourrait entraîner une consommation excessive de mémoire ; il est préférable de se limiter aux constantes, aux chaînes récurrentes, et aux chaînes utilisées telles qu'elles (c'est-à-dire non concaténées).

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.