[Session d'étude interne] Gestion des exceptions Java (2017/04/26)

0. Introduction


Personne cible


Ce que je veux dire

Expliquez les règles concernant les exceptions du point de vue des créateurs d'API et des utilisateurs d'API. L'API (Application Program Interface) suppose une méthode publique.


Livres de référence

Effective Java 2nd Edition

参考図書.jpg

Un livre écrit à l'époque de Java 6, un peu vieux, mais un bon livre. Les règles sont rédigées en mettant l'accent sur la clarté et la concision.


table des matières

  1. Résumé des exceptions
  2. Règles d'exception pour les utilisateurs d'API
  3. Règles d'exception pour les auteurs d'API
  4. Annexe

1. Résumé des exceptions


Quelles sont les exceptions?

Le traitement d'exception (reigaishori) consiste à suspendre (arrêter) le traitement en cours et à effectuer un autre traitement lorsqu'une anomalie se produit pendant que le programme exécute un certain traitement. L'anomalie qui se produit à ce moment est appelée une exception.

Gestion des exceptions Wikipedia


Exceptions vérifiées et exceptions d'exécution

Structure du type d'exception


java.lang.Exception
 -  IOException
 -  SQLException
 -  RuntimeException
     - NullPointerException
     - IllegalArgumentException

Syntaxe de gestion des exceptions (méthode d'appel à lancer)

Lors de l'utilisation du constructeur de java.io.FileReader.

throws définit l'exception que la méthode lève.

public FileReader(File file) throws FileNotFoundException

Que faire lors de l'appel d'une méthode qui lève une exception

try {
  FileReader fr = new FileReader(file);  
} catch(FileNotFoundException e) {
  //...
}
private void read(File file) throws FileNotFoundException {
    FileReader fr = new FileReader(file);  
}

Syntaxe de gestion des exceptions (lève explicitement Exception)

Utilisez le mot réservé throw.

private void read(File file) {
  if (file == null) {
     throw new NullPointerException("file is null");
  }
}

Les exceptions vérifiées doivent déclarer «throws» dans la méthode. Aucune exception d'exécution (telle que NullPointerException) n'est requise. Une description des exceptions vérifiées et des exceptions d'exécution sera donnée ultérieurement.


Syntaxe de gestion des exceptions (multi-capture)

Disponible à partir de Java 7.

Pour Java 6 ou version antérieure

catch (IOException ex) {
     logger.log(ex);
     throw ex;
} catch (SQLException ex) {
     logger.log(ex);
     throw ex;
}

Pour Java 7 ou version ultérieure

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

https://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/catch-multiple.html Référence


2. Règles d'exception pour les utilisateurs d'API


Ne pas ignorer les exceptions (élément 65)

Ignorer est le pire. Absolument pas.

try {
   ...
} catch(SomeException e) {}

Un bloc catch vide n'atteint pas le but de l'exception. Son but est de "forcer le traitement de conditions exceptionnelles".

Vue personnelle


N'utiliser des exceptions que pour des conditions exceptionnelles (point 57)

Qu'est-ce qui ne va pas? Une exception est utilisée pour déterminer la fin de la boucle.

int[] array = {1,2,3,4,5};
try {
	int i=0;
	while(true) {
		System.out.println(array[i++]);
        //Autre traitement
	}
} catch(ArrayIndexOutOfBoundsException e) {}

Les exceptions, comme leur nom l'indique, ne doivent être utilisées que pour des conditions exceptionnelles. Il ne doit jamais être utilisé pour des flux de contrôle normaux.


[Vue personnelle] Catch avec les exceptions appropriées

Je peux l'attraper avec java.lang.Exception, mais je l'attrape avec java.lang.Exception.

File file = new File("/tmp/sample.txt");
try {
  FileReader fr = new FileReader(file);  
} catch(Exception e) { //IOException est approprié
  //...
}

problème


Si vous pouvez l'attraper avec java.lang.Exception

Traitement du cadre, etc. Si vous n'arrêtez pas la propagation d'exception quelque part, votre système (par exemple Tomcat) tombera en panne.

La source suivante est l'endroit où la logique métier est appelée dans le cadre Terasoluna.

java:jp.terasoluna.fw.ex.aop.log.BLogicLogInterceptor.java


 public Object invoke(MethodInvocation invocation) throws Throwable {
       //...
        try {
           //Exécution de la logique métier
            result = invocation.proceed();
        } catch (Throwable e) {
            if (checkException(e)) {
                logger.error(e); //[Sortie d'exception]
                throw e;
            } else {
                logger.debug(e); //[Sortie d'exception]
                throw e;
            }
        }
}        

[Vue personnelle] La plage des blocs d'essai n'est pas trop large

Le traitement qui ne lève pas d'exception ne doit pas être décrit dans le bloc try si possible.

try {
  //Traitement autre que des fichiers(L'exception n'est pas levée)
  initialize();
  //Traitement lié aux fichiers
  File file = new File("/tmp/sample.txt");
  FileReader fr = new FileReader(file);  
} catch(IOException e) { 
  //...
}

problème


3. Règles d'exception pour les auteurs d'API


Utiliser des exceptions d'exécution pour les erreurs de programmation (élément 58)

La plupart des exceptions d'exécution indiquent des violations de conditions préalables. Une violation de condition préalable est que le client API n'adhère tout simplement pas au contrat défini par la spécification API.

Exceptions d'exécution fréquentes

http://qiita.com/yuba/items/d41290eca726559cd743 Référence

Exceptions que les utilisateurs d'API peuvent éviter, responsabilités des utilisateurs d'API.


Utiliser les exceptions vérifiées (exceptions vérifiées) pour les états récupérables (élément 58)

N'utilisez pas d'exceptions cochées pour les situations où l'appelant peut récupérer correctement.

Je ne suis pas sûr de "l'état récupérable".

Selon http://qiita.com/yuba/items/d41290eca726559cd743, "l'exception vérifiée est un système anormal qui n'est pas de la responsabilité de l'appelant."

Exceptions d'inspection fréquemment observées

Puisqu'il ne peut être évité, l'utilisateur de l'API est obligé de «penser au système anormal».


IOException est-il vraiment inévitable en premier lieu?

Si vous passez un chemin de fichier qui n'existe pas dans le constructeur FileReader, une FileNotFoundException se produira. Même si l'existence du fichier est confirmée, le fichier peut être supprimé immédiatement après cela, de sorte qu'il ne peut pas être complètement évité.

File file = new File("/tmp/sample.txt");
if (file.exists() ){ 
  //Si le fichier est supprimé ici, une exception se produira sur la ligne suivante
  FileReader fr = new FileReader(file);
}  

Mon avis

Si "ce n'est pas la responsabilité de l'utilisateur de l'API", cela ne semble pas être "la responsabilité du créateur de l'API". Peut-être que personne ne peut en prendre la responsabilité.

Le créateur de l'API a estimé qu'il lançait une exception de vérification dans le sens que "même si un système anormal se produit, ce n'est pas ma responsabilité".


Existe-t-il une exception de contrôle même sous la responsabilité de l'utilisateur de l'API?

La méthode java.text.DateFormat # parse lève une exception vérifiée ParseException.

ParseException-Si le début de la chaîne spécifiée ne peut pas être analysé.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
try {
	sdf.parse("abc"); //Lancer PrseException
} catch (ParseException e) {
	e.printStackTrace();
}

ʻInteger.parseInt lève une exception d'exécution NumberFormatException. SimpleDateFormat` n'est pas thread-safe et peut lever une exception vérifiée.


[Opinion personnelle] Ne lancez pas java.lang.Exception

/**Lecture de fichiers*/
List<String> read(File file) throws Exception {
  List<String> lines = new ArrayList<>();
  FileReader fr = new FileReader(file);
  //....
  return lines;
}  

problème


4. Annexe


Langage C pour lequel il n'y a pas de mécanisme de gestion des exceptions

L'erreur est représentée par une valeur de retour ou un argument de sortie.


/**
 * 0:Succès
 * -1:Erreur d'argument
 * -2:Erreurs liées au fichier
 * /
int read(char *file) {
  //...
}

int sub(char *file) {
  int rtn = read(file);
  return rtn;
}

int main() {
  int rtn = sub(file);
}

problème


Avantages et inconvénients des exceptions d'inspection

Seul Java implémente les exceptions vérifiées dans les principales langues. L'une ou l'autre des exceptions d'inspection est négative.

http://qiita.com/Kokudori/items/0fe9181d8eec8d933c98


enfin clause et retour

Lors du retour dans la clause try-catch-finally, si la clause finally est définie, l'intérieur de la clause finally est toujours exécuté avant le retour.

source-try.java


public class Try {
    public static void main(String[] args) {
        String i=TryCatch();
        System.out.println(i);
    }

    public static String TryCatch(){
        System.out.println("début!");
        String str = null;//Rendre nul
        try{
            str.toString();     //NullPointerException
            System.out.println("Hogehoge");
            return "Le retour de la clause Try.";
        }catch(Exception e){
            System.out.println("Fuga Fuga");
            return "Le retour de la clause Catch.";
        }finally{
            System.out.println("La clause finally a été exécutée.");
        }
    }
}

System.out


début!
Fuga Fuga
La clause finally a été exécutée.
Le retour de la clause Catch.

Extrait de http://qiita.com/eijenson/items/7e9e112e69b37f72353c


Break, continue, return, System.exit sont interdits dans la clause finally

Ceux-ci ne sont pas sujets à des erreurs ou des avertissements lorsqu'ils sont compilés avec javac. Cependant, lorsque j'utilise Eclipse, j'obtiens un avertissement concernant la pause, la poursuite et le retour que "le blocage final ne se termine pas correctement".

Extrait de http://www.atmarkit.co.jp/ait/articles/0611/22/news145.html

public class Try {
    public static void main(String[] args) {
        String i=TryCatch();
        System.out.println(i);
    }

    public static String TryCatch(){
        System.out.println("début!");
        String str = null;//Rendre nul
        try{
            str.toString();     //NullPointerException
            System.out.println("Hogehoge");
            return "Le retour de la clause Try.";
        }catch(Exception e){
            System.out.println("Fuga Fuga");
            return "Le retour de la clause Catch.";
        }finally{
            System.out.println("La clause finally a été exécutée.");
            return "Je serrai l'exception";//Faire un retour
        }
    }
}

System.out


début!
Fuga Fuga
La clause finally a été exécutée.
Je serrai l'exception

try-with-resources

Il peut être utilisé à partir de Java 7. fermer la syntaxe inutile

Avant Java SE 7, vous pouvez utiliser des blocs finally pour vous assurer que les ressources sont fermées, que l'instruction try se termine avec succès ou brusquement.

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
  BufferedReader br = new BufferedReader(new FileReader(path));
  try {
    return br.readLine();
  } finally {
    if (br != null) br.close();
  }
}

Lors de l'utilisation de l'instruction try-with-resources

static String readFirstLineFromFile(String path) throws IOException {
  try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
  }
}

Dans cet exemple, la ressource déclarée dans l'instruction try-with-resources est BufferedReader. La déclaration est entre parenthèses immédiatement après le mot-clé try. À partir de Java SE 7, la classe BufferedReader implémente l'interface java.lang.AutoCloseable. L'instance BufferedReader est déclarée avec une instruction try-with-resource, elle se ferme donc indépendamment du fait que l'instruction try s'est terminée avec succès ou brusquement (suite à la levée d'une IOException par la méthode BufferedReader.readLine). Peut être fait.

http://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html


«97 choses que les programmeurs devraient savoir» sur les exceptions

[97 choses que les programmeurs devraient savoir](http://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E6%9B%B8%E7%B1%8D/%E3%83%97%E3%83%AD%E3 % 82% B0% E3% 83% A9% E3% 83% 9E% E3% 81% 8C% E7% 9F% A5% E3% 82% 8B% E3% 81% B9% E3% 81% 8D97% E3% 81 % AE% E3% 81% 93% E3% 81% A8)

プログラマが知るべき.jpg


Site de référence

[Bonnes pratiques pour la gestion des exceptions en Java] (https://moneyforward.com/engineers_blog/2014/08/22/java%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E4%BE%8B%E5%A4%96%E5%87%A6%E7%90%86%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%BB%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9/)

Les exceptions vérifiées par Java sont des systèmes anormaux qui ne relèvent pas de la responsabilité de l'appelant

Historique de la gestion des erreurs

Grand péché dans un design exceptionnel


fin

Recommended Posts

[Session d'étude interne] Gestion des exceptions Java (2017/04/26)
Gestion des exceptions Java?
[Java] Gestion des exceptions
☾ Java / Gestion des exceptions
À propos de la gestion des exceptions Java
Gestion des exceptions Java
Résumé de la session d’étude interne des recrues [Java]
[Java] Pratique de la gestion des exceptions [Exception]
[Java] À propos de la gestion des exceptions try-catch
Règles d'utilisation pour la gestion des exceptions Java
Techniques de gestion des exceptions en Java
[Session d'étude interne] Bases de l'annotation Java (2017/11/02) ~ En construction ~
[Mémo de la session d'étude] Java Day Tokyo 2017
Gestion des exceptions
Compréhension étape par étape de la gestion des exceptions Java
[Pour les débutants en Java] À propos de la gestion des exceptions
Exception de traitement des exceptions
[Session d'étude interne] Introduction du "Code lisible"
Java (gestion des exceptions, threading, collection, fichier IO)
gestion des exceptions try-catch-finally Comment utiliser java
À propos de la gestion des exceptions
À propos de la gestion des exceptions
Étudions Java
gestion des exceptions ruby
[Java] Instance d'exception
Gestion des exceptions Ruby
[Java] Notes d'étude
Étudier Java 8 (répétable)
Mémorandum d'étude Java
Portée de session Java
Étudier Java Silver 1
Mémo de la session d'étude: Kansai Java Engineers Association 8/5 - Selenium
Questions sur la gestion des exceptions Java throw et try-catch
À propos de la gestion des exceptions Ruby
Pratique de gestion des exceptions (ArithmeticException)
Journée d'étude Java Silver 1
[java] Lancer une exception
Gestion des exceptions Spring Boot
Mémorandum de la session d'étude Javasilver
Étudier Java # 1 (type typique)
Ma note d'étude (Java)
[Java Silver] (Gestion des exceptions) À propos des instructions try-catch-finally et try-with-resource
Note de session d'étude: Kansai Java Engineers Association [Osaka] 7/12 - Cloud Native
Etudier Java # 2 (\ marque et opérateur)
Classes nécessitant une gestion des exceptions
Contenu d'apprentissage de base Java 7 (exception)
Première gestion des exceptions de Java (mémoire)
Étudier le tableau, la liste, la carte Java
Mémo de la méthode d'étude Java Silver
[Ruby] Gestion des exceptions dans les fonctions
Etude de Java # 7 (Type de syntaxe de branche)
Mémo d'étude Java 2 avec Progate
Étudier Java avec Progate Note 1
[Milight Design In-house Study Group # 5] Lisez docker-compose.yml et Dockerfile ligne par ligne
(Mémo d'apprentissage) Mesures Java de 2e année: points principaux du 4e trimestre (gestion des exceptions)
[Introduction à Java] À propos de la gestion des exceptions (try-catch-finally, exception vérifiée, exception non vérifiée, throws, throw)
Une histoire sur la rédaction d'un calcul de ratio lors d'une session d'étude en interne