substring() en Java sans erreur - indices, exceptions et Unicode

Denis Ribeiro .

16 septembre 2026

Explication de la méthode `substring` en Java. Elle renvoie une chaîne à partir d'un index spécifié.

Découper une chaîne de caractères paraît simple, jusqu’au moment où un indice décalé provoque une exception ou tronque un caractère. En Java, la méthode substring() permet d’extraire rapidement une portion de texte, à condition de bien comprendre ses indices, ses limites et les cas où une autre méthode convient mieux.

Les repères essentiels pour extraire une portion de texte en Java

  • Deux signatures existent avec substring(beginIndex) et substring(beginIndex, endIndex).
  • L’indice de début est inclus, tandis que l’indice de fin est exclu.
  • Un indice invalide déclenche une StringIndexOutOfBoundsException.
  • Les chaînes Java sont immutables : l’extraction retourne une nouvelle valeur sans modifier l’original.
  • Pour des caractères Unicode complexes, il faut parfois raisonner en points de code plutôt qu’en simples indices.

Explication de la méthode `substring` en Java. Elle retourne une chaîne à partir d'un index spécifié.

Comprendre les deux formes de substring

La méthode appartient à la classe String et sert à récupérer une sous-chaîne à partir d’un texte existant. Dans mes propres exemples Java, je commence presque toujours par visualiser les positions des caractères, car c’est le moyen le plus rapide d’éviter les erreurs d’indice.

String texte = "Bonjour Java";

String partie1 = texte.substring(8);
String partie2 = texte.substring(0, 7);

System.out.println(partie1); // Java
System.out.println(partie2); // Bonjour

La première forme reçoit uniquement beginIndex. Elle extrait le texte depuis cet indice jusqu’à la fin de la chaîne. La seconde reçoit deux indices et récupère les caractères situés entre le début inclus et la fin exclue.

String langage = "Java";

String resultat = langage.substring(1, 3);

System.out.println(resultat); // av

Dans cet exemple, l’indice 1 correspond à a, tandis que l’indice 3 marque la limite après v. Le caractère placé à la position finale n’est donc jamais inclus. Cette règle peut sembler déroutante au début, mais elle rend les calculs de longueur beaucoup plus cohérents, car la taille de l’extrait vaut simplement endIndex - beginIndex.

Lire correctement les indices et les limites

Java numérote les caractères à partir de 0. Pour la chaîne "Java", J se trouve à la position 0, a à la position 1, v à la position 2 et a à la position 3. La longueur totale est 4, ce qui signifie que l’indice de fin peut aller jusqu’à 4, sans désigner un caractère concret.

Expression Résultat Explication
"Java".substring(0) "Java" Extrait toute la chaîne
"Java".substring(1) "ava" Commence à l’indice 1
"Java".substring(0, 2) "Ja" L’indice 2 est exclu
"Java".substring(4) "" Retourne une chaîne vide

Les erreurs apparaissent lorsque le début est négatif, dépasse la longueur du texte, ou lorsque la fin est supérieure à cette longueur. Java refuse également un intervalle où le début est supérieur à la fin. Selon le cas, le programme lève une exception de type StringIndexOutOfBoundsException ou une exception d’index équivalente.

String code = "ABC";

String erreur1 = code.substring(4);    // Exception
String erreur2 = code.substring(2, 1); // Exception
String erreur3 = code.substring(-1);   // Exception

Pour du texte fourni par un utilisateur, je ne passe jamais directement des indices non contrôlés à substring(). Une vérification simple rend le comportement prévisible et évite qu’une saisie inattendue fasse tomber tout le traitement.

int debut = 2;
int fin = 8;

if (debut >= 0 && fin <= texte.length() && debut <= fin) {
    String extrait = texte.substring(debut, fin);
}

Extraire un texte dans des cas concrets

Récupérer une extension de fichier

Pour extraire une extension, je préfère d’abord rechercher le dernier point avec lastIndexOf(). Cette approche fonctionne mieux pour des noms comme archive.backup.zip, car elle conserve uniquement zip.

String nomFichier = "archive.backup.zip";
int positionPoint = nomFichier.lastIndexOf('.');

String extension = positionPoint >= 0
        ? nomFichier.substring(positionPoint + 1)
        : "";

System.out.println(extension); // zip

La condition est importante. Sans elle, un fichier dépourvu d’extension pourrait produire un résultat incorrect ou une logique difficile à maintenir. Pour une application réelle, je traite aussi séparément les noms qui se terminent par un point ou qui commencent par un point, comme certains fichiers cachés.

Isoler une partie d’un identifiant

Une autre utilisation fréquente consiste à récupérer un préfixe ou un segment dans un identifiant. Ici, la lisibilité compte davantage que la compacité, surtout si la valeur sera modifiée plus tard.

String reference = "FR-2026-0048";

String pays = reference.substring(0, 2);
String annee = reference.substring(3, 7);
String numero = reference.substring(8);

System.out.println(pays);   // FR
System.out.println(annee);  // 2026
System.out.println(numero); // 0048

Ce code repose sur un format fixe. Si les données peuvent contenir des séparateurs variables ou des segments manquants, split() ou un parseur dédié sera souvent plus sûr. J’évite de multiplier les indices codés en dur dès que le format devient évolutif.

Lire aussi : À quoi sert Java ? Usages réels et pertinence en 2026

Afficher un aperçu limité

Pour afficher un extrait de description, il est courant de limiter le texte à un nombre maximal de caractères. La borne doit cependant être comparée à la longueur réelle de la chaîne.

String description = "Une description assez longue pour être abrégée.";
int limite = 20;

String apercu = description.length() > limite
        ? description.substring(0, limite) + "..."
        : description;

System.out.println(apercu);

Cette technique convient à un aperçu simple, mais elle peut couper un mot au milieu. Dans une interface destinée au public, je préfère parfois rechercher le dernier espace avant la limite afin d’obtenir un rendu plus naturel.

Choisir entre substring, split et les expressions régulières

substring() est idéale lorsque les positions sont connues ou calculées précisément. Elle devient moins adaptée quand il faut découper un texte selon un séparateur, reconnaître plusieurs formats ou valider une structure complexe.

Besoin Méthode conseillée Pourquoi
Extraire une plage d’indices substring() Simple et lisible
Séparer une chaîne avec un délimiteur split() Adapté aux virgules, espaces ou tirets
Vérifier un préfixe ou un suffixe startsWith() ou endsWith() Évite une extraction inutile
Rechercher une structure variable Pattern et Matcher Utile pour les formats complexes
Traiter plusieurs modifications StringBuilder Évite de créer trop de chaînes intermédiaires

Par exemple, pour une adresse e-mail, chercher directement le caractère @ est généralement plus clair que de supposer une position fixe.

String email = "contact@exemple.fr";
int positionArobase = email.indexOf('@');

if (positionArobase > 0) {
    String utilisateur = email.substring(0, positionArobase);
    String domaine = email.substring(positionArobase + 1);
}

Je ne présenterais toutefois pas ce fragment comme une validation complète d’adresse e-mail. Il montre uniquement comment extraire deux segments. Pour valider réellement une adresse, il faut une règle métier plus précise et gérer les cas particuliers.

Éviter les erreurs liées à l’immutabilité et à Unicode

Une chaîne Java est immuable. Cela signifie que substring() ne modifie jamais la variable d’origine, même si le résultat est stocké dans une autre variable. Cette distinction est souvent oubliée dans les premiers programmes.

String original = "Bonjour";
String extrait = original.substring(0, 3);

System.out.println(original); // Bonjour
System.out.println(extrait);  // Bon

Si je veux remplacer la valeur initiale, je dois explicitement la réaffecter. Le fait d’appeler la méthode seul ne produit aucun changement visible dans la variable originale.

String texte = "Bonjour";
texte.substring(0, 3);

System.out.println(texte); // Bonjour

texte = texte.substring(0, 3);
System.out.println(texte); // Bon

Autre point plus subtil, les indices de String reposent sur des unités UTF-16. Pour les caractères représentés par une paire spéciale, comme certains emojis, couper au milieu peut produire un texte invalide ou visuellement surprenant.

String texte = "A😀B";

System.out.println(texte.length()); // 4

Le symbole visible entre A et B occupe ici deux unités Java. Lorsque le traitement doit respecter les caractères Unicode réels, j’utilise plutôt codePoints(), offsetByCodePoints() ou une bibliothèque spécialisée. Pour du texte technique limité à l’alphabet courant, substring() reste généralement parfaitement appropriée.

Adopter une méthode fiable dans son code

La règle la plus pratique consiste à calculer les bornes à partir du contenu, puis à les contrôler avant l’extraction. Une petite méthode utilitaire peut protéger les appels répétés, mais elle doit avoir un comportement clair lorsque les indices sont invalides.

static String extraireSiValide(String texte, int debut, int fin) {
    if (texte == null) {
        return "";
    }

    if (debut < 0 || fin > texte.length() || debut > fin) {
        return "";
    }

    return texte.substring(debut, fin);
}

Retourner une chaîne vide n’est pas toujours le meilleur choix. Dans une logique métier stricte, je préfère parfois lancer une exception explicite, car masquer une donnée incorrecte rend le diagnostic plus difficile. Le choix dépend donc du contrat de la méthode, et non d’une règle universelle.

Pour les performances, une extraction occasionnelle coûte peu et reste très lisible. En revanche, créer des milliers de sous-chaînes dans une boucle peut augmenter les allocations mémoire. Dans ce cas, je mesure d’abord avec un profilage réel avant de remplacer le code par un StringBuilder ou une autre structure, car l’optimisation prématurée rend souvent le traitement moins compréhensible sans gain mesurable.

Le bon réflexe avant chaque extraction

Pour extraire une portion de texte en Java, je vérifie trois éléments. Je confirme d’abord que l’indice de départ correspond bien au caractère voulu, puis que la borne finale est exclusive, et enfin que les données peuvent réellement respecter le format attendu.

substring() reste une méthode courte, rapide et très efficace pour les découpages déterministes. Dès que le texte devient variable, multilingue ou structuré par des séparateurs, je choisis un outil adapté plutôt que de forcer une succession d’indices. Ce simple réflexe évite la plupart des bugs et produit un code beaucoup plus facile à relire.

Questions fréquentes

substring(beginIndex) extrait le texte depuis l’indice de début jusqu’à la fin. substring(beginIndex, endIndex) extrait les caractères du début inclus jusqu’à la fin exclue, avec une longueur égale à endIndex - beginIndex.
Java lève une StringIndexOutOfBoundsException lorsque l’indice de début est négatif ou dépasse la longueur, lorsque la fin est trop grande, ou lorsque le début est supérieur à la fin. Avant l’extraction, contrôlez notamment que debut >= 0, que fin <= texte.length() et que debut <= fin.
substring() convient aux positions connues ou calculées précisément. Utilisez split() pour séparer une chaîne avec un délimiteur, et Pattern ou Matcher lorsqu’il faut reconnaître une structure variable ou complexe.
substring() ne modifie jamais la chaîne d’origine : il faut réaffecter le résultat pour remplacer sa valeur. Les indices reposent sur des unités UTF-16 ; certains emojis occupent donc deux unités Java. Pour respecter les caractères Unicode réels, utilisez notamment codePoints() ou offsetByCodePoints().
Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

unicode expressions régulières sous-chaînes indices stringbuilder
Autor Denis Ribeiro
Denis Ribeiro
Je m'appelle Denis Ribeiro et j'ai quatre ans d'expérience dans le domaine de la technologie, en particulier dans les domaines du web, de l'intelligence artificielle, des réseaux et de la sécurité. Mon intérêt pour ces sujets a commencé dès mon plus jeune âge, lorsque j'ai découvert à quel point la technologie pouvait transformer notre quotidien. J'aime expliquer des concepts complexes de manière simple, afin d'aider mes lecteurs à mieux comprendre les enjeux actuels et futurs de notre monde numérique. Dans mes écrits, je m'efforce de fournir des informations utiles, précises et à jour. Je prends le temps de vérifier mes sources et de comparer les informations, tout en suivant les dernières tendances du secteur. Mon objectif est de rendre l'apprentissage accessible à tous, en organisant mes connaissances de manière claire et structurée, afin que chacun puisse naviguer avec confiance dans cet univers en constante évolution.
Commentaires (0)
Ajouter un commentaire