Skip to content

Latest commit

 

History

History
183 lines (156 loc) · 8.66 KB

EXCEPTIONS_JAVA.md

File metadata and controls

183 lines (156 loc) · 8.66 KB

Les exceptions en Java

Préambule

Il existe deux types d'exceptions :

  • Les checked exceptions qui sont des exceptions qui doivent être encadrées d'un try/catch.
  • Les unchecked exceptions qui sont des exceptions qui n'ont pas besoin d'être déclarées dans le code.

Checked Exception

Error

La classe Error est invoquée lors d'une erreur grave intervenue dans la JVM, elle stoppe immédiatement le programme.

Exception

La classe Exception est invoquée lors d'une erreur moins grave, elle peut stopper le programme.

Unchecked Exception

RuntimeException

La classe RuntimeException hérite de la classe Exception.
Toutes les classes héritant de la classe RuntimeException sont des exceptions de type unchecked.

Méthode :

Compréhension :

Une stacktrace est faite pour comprendre une erreur, elle contient toutes les informations nécessaires à la résolution de cette dernière.

java.lang.NullPointerException: Main cannot be null
	at ga.enimaloc.B.c(B.java:16)
	at ga.enimaloc.B.b(B.java:24)
	at ga.enimaloc.A.a(A.java:35)
	at ga.enimaloc.Main.main(Main.java:7)

Composition de la stacktrace :

  • java.lang.NullPointerException est la classe qui correspond à l'erreur, elle permet de déterminer le nom de l'exception et de savoir de quelle librairie elle provient.
  • Main cannot be null est le message fourni lors de l'invocation. Il précise souvent la raison pour laquelle l'exception a été invoquée.
  • Le reste en dessous
	at ga.enimaloc.B.c(B.java:16)
	at ga.enimaloc.B.b(B.java:24)
	at ga.enimaloc.A.a(A.java:35)
	at ga.enimaloc.Main.main(Main.java:7)

indique l'acheminement de l'exception commençant de bas en haut (le haut étant la méthode contenant la première instruction ayant causé l'erreur), chaque ligne se compose de la classe (et de son package), de la méthode, du fichier source, et de la ligne de l'invocation.
⚠️ Attention : cet acheminement ne contient pas forcément que vos classes, veuillez bien chercher les lignes concernées par l'erreur, de haut en bas, lisez chaque ligne et arrêtez-vous à la dernière concernant votre code.

Maintenant, si on essaie de transposer en français, cela donnerait :
NullPointerException faisant partie du package java.lang a été invoquée à la ligne 16 du fichier B.java présent dans le package ga.enimaloc en précisant Main cannot be null.

Correction

Première cause : le code

Dans ce cas-ci, vous devez comprendre dans quelle partie et quand est-ce que l'erreur est déclenchée en suivant votre code et en déboggant si besoin.

Exemple :

public class Main {

    private static List<Object> list = null;

    public static void main(String[] args) {
        list.add(new Object());
    }
    
}

À la ligne list.add(new Object());, vous obtiendrez une NullPointerException car list est null. Pour corriger cela, il faudrait affecter une valeur à la liste via list = new ArrayList(); ou directement à l'initialisation de cette dernière comme ceci : private static List<Object> list = new ArrayList();.

Deuxième cause : un choix de l'utilisateur

Ici, vous devrez passer par un try/catch ou contrôler la valeur entrée pour éviter que l'utilisateur ne provoque une erreur.
Exemple :

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Entrer un nombre :");
        int i = scanner.nextInt();
    }
    
}

Ici, tout se passe bien si l'utilisateur entre un entier, mais si l'utilisateur entre quelque chose d'autre comme un mot, l'exception NumberFormatException sera lancée. Afin de corriger cela, nous devrions faire :

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Entrer un nombre :");
        try {
            int i = scanner.nextInt();
        } catch (NumberFormatException ignored) {
            System.out.println("Le nombre que vous avez entré n'est pas valide");
        }
    }
    
}

Troisième cause : l'environnement dans lequel l'application est lancée

Comme pour la deuxième cause, vous devrez passer par un try/catch ou faire une vérification. Exemple :

public class Main {

    public static void main(String[] args) {
        try {
            URL url = new URL("https://www.google.com/");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            InputStream inputStream = conn.getInputStream();
            int ch;
            StringBuffer buffer = new StringBuffer();
            while((ch = inputStream.read()) != -1) {
                buffer.append((char) ch);
            }
            String content = buffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

Ceci lancerait l'exception java.net.UnknownHostException si la machine n'a aucun accès à internet, pour éviter cela, il faudrait vérifier que le client est bien connecté en ajoutant un catch de java.net.UnknownHostException :

public class Main {

    public static void main(String[] args) {
        try {
            URL url = new URL("https://www.google.com/");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            InputStream inputStream = conn.getInputStream();
            int ch;
            StringBuffer buffer = new StringBuffer();
            while((ch = inputStream.read()) != -1) {
                buffer.append((char) ch);
            }
            String content = buffer.toString();
        } catch (UnknownHostException e) {
            System.out.println("Aucune connexion n'est détectée !");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

Quelques erreurs courantes

NullPointerException :

Une NullPointerException (aussi connue par l'abréviation NPE) est une exception héritant de la classe RuntimeException, c'est donc une unchecked exception.

Elle est invoquée quand le programme essaie d'accéder à une valeur null, cela inclut :

  • L'invocation de la méthode d'instance d'un objet null.
  • La récupération/modification d'un élément dans un tableau défini à null.
  • Invoquer une exception qui est null.

IndexOutOfBoundException :

Une IndexOutOfBoundException (ou sous forme abrégée IOOB) est une exception héritant de la classe RuntimeException, c'est donc une unchecked exception.

Elle est invoquée quand le programme essaie d'accéder à un élément avec un index invalide (inférieur à 0 ou supérieur à la limite de l'objet).

StackOverflowError :

Une StackOverflowError est une erreur héritant de la classe Error, c'est donc une erreur grave.

Elle est invoquée quand le programme appelle, dans une méthode, cette même méthode sans sortie possible, ce qui causerait une boucle infinie.

public class Main {

    public static void main(String[] args) {
        int incrementedNumber = increment(0);
        System.out.println(incrementedNumber);
    }

    public int increment(int i) {
        return increment(i + 1);
    }
    
}

Ce code provoquerait une StackOverflowError sur la ligne int incrementedNumber = increment(0);

NoClassDefFoundError :

Une NoClassDefFoundError est une erreur héritant de la classe Error, c'est donc une erreur grave.

Elle est invoquée quand le programme essaie de charger une classe inexistante.