Maison  >  Article  >  Java  >  Connaissance de base des exceptions Java et de la gestion des erreurs

Connaissance de base des exceptions Java et de la gestion des erreurs

高洛峰
高洛峰original
2017-01-18 14:46:311456parcourir

Exceptions et erreurs :
Exceptions : les erreurs de programme en Java sont principalement des erreurs de syntaxe et des erreurs sémantiques. Les erreurs qui se produisent lorsqu'un programme est compilé et exécuté sont collectivement appelées exceptions, qui sont des VM (machine virtuelle) Un moyen de notifier. vous, dans lequel la VM vous fait savoir que vous (le développeur) avez commis une erreur et que vous avez maintenant la possibilité de la corriger. Les classes d'exception sont utilisées en Java pour représenter les exceptions, et différentes classes d'exception représentent différentes exceptions. Mais toutes les exceptions en Java ont une classe de base appelée Exception.
Erreur : Il s'agit d'un problème grave qui ne peut être intercepté par une application raisonnable. La plupart sont des anomalies. Une erreur est une défaillance de la VM (bien qu'il puisse s'agir de n'importe quel service au niveau du système). Par conséquent, les erreurs sont difficiles à gérer et le développeur moyen (pas vous, bien sûr) ne peut pas gérer ces erreurs, telles qu'un débordement de mémoire. Comme les exceptions, les classes d'erreurs sont utilisées pour représenter les erreurs en Java, et différentes classes d'erreurs représentent différentes erreurs. Mais toutes les erreurs en Java ont une classe de base appelée Error.
Pour résumer, nous pouvons savoir que la différence la plus essentielle entre les exceptions et les erreurs est que les exceptions peuvent être gérées par les développeurs, tandis que les erreurs sont natives du système et ne peuvent généralement pas être gérées et ne nécessitent pas que nos programmeurs les gèrent.
1. Une exception est un événement qui se produit lors de l'exécution d'un programme qui interrompt l'exécution des instructions normales
2. Erreur, une action ou une instance qui s'écarte du comportement acceptable du code
Classification structurelle exceptionnelle :
1. Exception d'exécution (exception non vérifiée)
2. Exception au moment de la compilation (exception vérifiée)
L'exception d'exécution est RuntimeException ; les autres sont toutes des exceptions de compilation
en Java Exception et erreur Error ont une classe parent commune Jetable.
Exception d'erreur
Plusieurs sous-classes de runtimeException
1 java.lang.ArrayIndexOutOfBoundsException
Exception hors limites de l'index de tableau. Levé lorsque l'index du tableau est négatif ou supérieur ou égal à la taille du tableau.
2. java.lang.ArithmeticException
Exception de condition arithmétique. Par exemple : division entière par zéro, etc.
3. java.lang.NullPointerException
Exception de pointeur nul. Cette exception est levée lorsque l'application tente d'utiliser null lorsqu'un objet est requis. Par exemple : appeler la méthode d'instance de l'objet nul, accéder à l'attribut
de l'objet nul, calculer la longueur de l'objet nul, utiliser l'instruction throw pour lancer null, etc.
java.lang. ClassNotFoundException
Exception de classe introuvable . Lorsque l'application tente de construire une classe basée sur un nom de classe sous la forme d'une chaîne et que le fichier de classe avec le nom correspondant est introuvable après avoir parcouru le CLASSPAH,
cette exception est levée.
Gestion des exceptions :
try{}catch{}
try{}catch{}finally{} Le bloc de code final sera exécuté, qu'il y ait ou non une exception
try{}finally {} est également possible. Il peut être utilisé en combinaison mais catch{}finally{} ne peut pas être utilisé
Remarque : dans la relation d'héritage, la sous-classe remplace la méthode de la classe parent et la portée des exceptions levées ne peut pas être plus large. que la classe parent

Utilisation des exceptions
Cette partie sur l'utilisation des exceptions est principalement du code de démonstration, que nous rencontrerons en cours d'écriture de code (bien sûr seulement une petite partie), voulez-vous pour inspirer les autres !

Exemple 1. Cet exemple démontre principalement le flux d'exécution du code après qu'une exception se produit en comparant deux méthodes.

public static void testException1() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("异常出现前");
try {
System.out.println(ints[4]);
System.out.println("我还有幸执行到吗");// 发生异常以后,后面的代码不能被执行
} catch (IndexOutOfBoundsException e) {
System.out.println("数组越界错误");
}
System.out.println("异常出现后");
}
/*output:

异常出现前
数组越界错误
常出现后
*/
 代码如下 复制代码 
public static void testException2() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("异常出现前");
System.out.println(ints[4]);
System.out.println("我还有幸执行到吗");// 发生异常以后,他后面的代码不能被执行
}

Tout d'abord, soulignez les lacunes de l'exemple. IndexOutofBoundsException est une exception non vérifiée, il n'est donc pas nécessaire d'essayer...catch... pour afficher la capture, mais mon objectif est pour utiliser différentes méthodes pour la même exception. La méthode de traitement, voyez quelle différence cela aura et le résultat (ici, je ne peux l'utiliser que pendant un moment). Lorsqu'une exception se produit, la première méthode sort simplement du bloc try, mais le code derrière elle sera toujours exécuté. Mais le deuxième type est différent et sort directement de la méthode, qui est plus difficile. De la première méthode, nous voyons que try...catch... est une garantie « transactionnelle ». Son objectif est de garantir que le programme se termine dans des circonstances anormales, et il informe également le programmeur des informations détaillées sur le programme. l'erreur (les détails dépendent parfois de la conception du programmeur).
Exemple 2. Relancer l'exception

public class Rethrow {
public static void readFile(String file) throws FileNotFoundException {
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.err.println("不知道如何处理该异常或者根本不想处理它,但是不做处理又不合适,这是重新抛出异常交给上一级处理");
//重新抛出异常
throw e;
}
}

public static void printFile(String file) {
try {
readFile(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
printFile("D:/file");
}
}

L'intention de l'exception est bonne, essayons de réparer le programme, mais en réalité les chances de le réparer sont très faibles, nous utilisons souvent pour enregistrer le message d'erreur. Si vous en avez assez de gérer constamment les exceptions, les relancer peut être un bon soulagement pour vous. Lancez cette exception inchangée au niveau supérieur, à la personne qui appelle cette méthode, et laissez-la y réfléchir. De ce point de vue, les exceptions Java (faisant bien sûr référence aux exceptions vérifiées) nous ont causé beaucoup de problèmes, même si leur point de départ est bon.

Exemple 3. Utilisation de la chaîne d'exceptions et de la perte d'exception

ExceptionA,ExceptionB,ExceptionC
public class ExceptionA extends Exception {
public ExceptionA(String str) {
super();
}
}

public class ExceptionB extends ExceptionA {

public ExceptionB(String str) {
super(str);
}
}

public class ExceptionC extends ExceptionA {
public ExceptionC(String str) {
super(str);
}
}

Situation de perte d'exception :

public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}

static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
throw c;
}
}

public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}

}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:19)
*/

Pourquoi seule l'exceptionC est-elle imprimée mais pas l'exceptionB ? Analysons cela vous-même !
La situation ci-dessus équivaut à manquer une exception, ce qui est très désavantageux dans notre processus de dépannage. Alors, que devons-nous faire lorsque nous rencontrons la situation ci-dessus ? C'est là qu'intervient le chaînage des exceptions : enregistrer les informations sur les exceptions afin que vous puissiez lancer une autre exception sans perdre l'exception d'origine.

public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}

static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
//异常连
c.initCause(e);
throw c;
}
}

public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}

}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:21)
Caused by: exception.ExceptionB
at exception.NeverCaught.f(NeverCaught.java:5)
at exception.NeverCaught.g(NeverCaught.java:10)
... 1 more
*/

这个异常链的特性是所有异常均具备的,因为这个initCause()方法是从Throwable继承的。
例4. 清理工作
清理工作对于我们来说是必不可少的,因为如果一些消耗资源的操作,比如IO,JDBC。如果我们用完以后没有及时正确的关闭,那后果会很严重,这意味着内存泄露。异常的出现要求我们必须设计一种机制不论什么情况下,资源都能及时正确的清理。这就是finally。

public void readFile(String file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));
// do some other work
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

例子非常的简单,是一个读取文件的例子。这样的例子在JDBC操作中也非常的常见。(所以,我觉得对于资源的及时正确清理是一个程序员的基本素质之一。)
Try...finally结构也是保证资源正确关闭的一个手段。如果你不清楚代码执行过程中会发生什么异常情况会导致资源不能得到清理,那么你就用try对这段"可疑"代码进行包装,然后在finally中进行资源的清理。举一个例子:

public void readFile() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work

//close reader
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} 
}

我们注意一下这个方法和上一个方法的区别,下一个人可能习惯更好一点,及早的关闭reader。但是往往事与愿违,因为在reader.close()以前异常随时可能发生,这样的代码结构不能预防任何异常的出现。因为程序会在异常出现的地方跳出,后面的代码不能执行(这在上面应经用实例证明过)。这时我们就可以用try...finally来改造:

public void readFile() {
BufferedReader reader = null;
try {
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work

// close reader
} finally {
reader.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

及早的关闭资源是一种良好的行为,因为时间越长你忘记关闭的可能性越大。这样在配合上try...finally就保证万无一失了(不要嫌麻烦,java就是这么中规中矩)。
再说一种情况,假如我想在构造方法中打开一个文件或者创建一个JDBC连接,因为我们要在其他的方法中使用这个资源,所以不能在构造方法中及早的将这个资源关闭。那我们是不是就没辙了呢?答案是否定的。看一下下面的例子:

public class ResourceInConstructor {
BufferedReader reader = null;
public ResourceInConstructor() {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream("")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public void readFile() {
try {
while(reader.readLine()!=null) {
//do some work
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void dispose() {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

这一部分讲的多了一点,但是异常确实是看起来容易用起来难的东西呀,java中还是有好多的东西需要深挖的

更多java异常与错误处理基本知识相关文章请关注PHP中文网!


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn