throw, signifiant "lancer, lancer, lancer". Throw, Throws et Throwable sont tous utilisés pour la gestion des exceptions.
Throwable est la classe parent de niveau supérieur de la branche de gestion des exceptions en Java. L'implémentation de toutes les autres gestions d'exceptions dépend de Throwable
Ouvrez la documentation officielle Java (version Java8) et trouvez Throwable, c'est direct. sous-classe pour les erreurs et les exceptions.
La caractéristique des erreurs et des exceptions est que les exceptions d'erreur ne peuvent pas être gérées par le programme et ne peuvent être laissées qu'à une intervention manuelle pour modifier le code, comme un débordement de pile, un débordement de tas, etc.; détectés à l’avance et traités efficacement.
Dans les erreurs, les erreurs courantes incluent le débordement de pile, le débordement de tas, etc.
Par exemple, StackOverflowError
public class ErrorTest { public static void main(String[] args) { main(args); } }
Récursion infinie, l'exécution de ce programme signalera une exception de débordement de pile.
Un autre exemple est l'exception de tas, OutOfMemoryError
public class ErrorTest { public static void main(String[] args) { Integer[] testArray = new Integer[1024*1024*1024]; } }
Il existe de nombreuses exceptions bien connues dans Exception, telles que NullPointerException (exception de pointeur nul), ArrayIndexOutOfBoundsException (sous tableau hors de limites), NumberFormatException (exception de formatage des nombres), etc.
public class ExceptionTest { public static void main(String[] args) { int[] testArray = null; System.out.println(testArray[0]); //空指针异常 } }
public class ExceptionTest { public static void main(String[] args) { int[] testArray = new int[3]; System.out.println(testArray[3]); //数组下标越界 } }
public class ExceptionTest { public static void main(String[] args) { String num = "abc"; System.out.println(Integer.parseInt(num)); //数字格式化异常 } }
throws doit être appliqué lors de la déclaration de la méthode pour indiquer les types d'exceptions qui peuvent se produire lorsque cette méthode est exécutée. Une fois qu'une exception se produit lors de l'exécution de la méthode, un objet de la classe d'exception sera généré au niveau du code d'exception. Lorsque cet objet répond au type d'exception après Throws, il sera lancé. Il y a deux processus ici. Lorsqu'il y a une exception dans le code,
1 Génère un objet d'exception ;
2 lance l'exception et lance l'objet d'exception
throws et try-catch-finally. deux types de gestion des exceptions.
try-catch-finally gère activement l'exception lorsqu'une exception se produit, afin que le programme puisse continuer à s'exécuter ; while throws attrape l'exception et lance l'objet d'exception vers le haut sans réellement gérer l'exception.
Le soi-disant lancement d'un objet d'exception vers le haut consiste à remettre l'objet d'exception à l'appelant pour traitement. Par exemple, la méthode A appelle la méthode B, B lance une exception via des lancers et A peut choisir d'utiliser try-catch-finally. pour gérer l'exception, ou Continuez à lancer des objets d'exception vers le haut jusqu'à ce que l'exception soit réellement gérée. S'il n'existe aucun moyen de gérer les exceptions, l'objet d'exception sera finalement renvoyé à la JVM, provoquant l'arrêt du programme.
@Test public void throwsTest(){ //调用者解决抛出的异常 try{ formatChange("abc"); } catch (NumberFormatException e){ System.out.println("转换格式错误!"); } catch (Exception e){ System.out.println("出现错误"); } } private int formatChange(String str) throws NumberFormatException{ //出现异常向上抛出 return Integer.parseInt(str); }
——Comment choisir essayer-attraper-finalement ou lancer ?
Lorsqu'il y a une exception dans une méthode qui doit être gérée, dans la plupart des cas, vous pouvez soit choisir try-catch-finally pour gérer l'exception directement, soit choisir throws pour lancer l'exception vers le haut et la laisser au appelant à gérer (l'exception est levée. En fin de compte, il doit y avoir une partie qui gère réellement cette exception. Comment la gérer ? Ou utilisez try-catch-finally. Cependant, lorsque le cas est exécuté, vous avez plus de liberté de choix. Suite à deux situations, vous devez suivre certaines règles (si elles sont ajoutées, merci de le signaler).
Si la méthode surchargée dans la classe parent n'utilise pas de lancers pour lever une exception, la méthode surchargée dans la sous-classe ne peut pas utiliser de lancers pour lancer une exception, ce qui signifie que try-catch-finally doit être utilisé dans ce cas. traiter avec.
Dans la méthode A, plusieurs autres méthodes sont appelées successivement. Ces méthodes sont exécutées dans une relation progressive et beaucoup d'entre elles ont des exceptions qui doivent être gérées. Dans ce cas, il est recommandé d'utiliser des lancers pour les différentes méthodes en cours. appelé. Lancez les exceptions vers le haut. Dans la méthode A, utilisez try-catch-finally pour gérer ces exceptions de manière uniforme.
Concernant le premier, il s'agit d'une stipulation selon laquelle l'exception levée par la méthode surchargée dans la sous-classe utilisant les lancers ne doit pas être plus grande que la plage d'exceptions levée par la méthode surchargée dans la classe parent. Par exemple, si la méthode B de la classe parent lève NullPointerException, la méthode substituée B de la sous-classe ne peut pas lever d'exceptions telles que Exception qui ont une plage plus large que NullPointerException si la méthode substituée de la classe parent ne lève pas si une exception se produit ; , la sous-classe ne peut pas lever d'exception.
Pourquoi ? Montrez un morceau de code.
//假设父类中的方法B抛出NullPointerException异常,子类中的方法B可以抛出Exception private void test(ParentClassTest parent){ try{ parent.B(); } catch(NullPointerException e){ System.out.println("出现了空指针异常"); } }
Dans cet exemple, en supposant que la méthode B de la classe parent renvoie NullPointerException, la méthode B remplacée dans la sous-classe peut lancer une exception. Ensuite, si les paramètres passés dans la méthode de test sont des objets instanciés de la classe parent, alors il n'y a aucun problème pour appeler la méthode de test. Si le paramètre transmis est un objet instancié de la sous-classe, et que la méthode B réécrite par la sous-classe est appelée, une exception peut être levée et la structure try-catch ne peut pas supprimer cette exception. Il s'agit évidemment d'une opération raisonnable. .
针对第二条,假设方法A中调用了方法C、D、E,这三个方法都有可能产生异常,且存在递进关系,也就是D、E执行需要C执行完成、E执行依赖C、D执行完成。那么就推荐在C、D、E中向上抛出异常,在方法A中集中处理。为什么?如果C、D、E都是向上抛出异常,而A使用try-catch-finally去处理这个异常,如果某个方法真的出现异常,则不再继续执行。而如果C、D、E都使用try-catch-finally直接解决掉异常,那么即使产生了异常,方法A也不会接收到异常的产生,那么还会接着往下执行,但是C出现了异常,再执行D、E没有任何意义。
如果在程序编写时有手动抛出异常的需求,则可以使用throw
throw使用在方法体内。与try-catch-finally和throws都不同,异常处理的两个阶段:1.遇到异常,生成异常对象;2.捕获到异常,进行抛出或处理。try-catch-finally和throws都处在第二个阶段,都是捕获到异常后的相关处理,一般使用系统根据异常类型自动生成的异常对象进行处理。而throw应用在第一阶段,手动地产生一个异常对象。
举一个例子,判断一个数值是否为非负数,如果为负数,则抛出异常。
class ThrowTest{ private int Number; public void judge(int num){ if(num>=0){ this.Number = num; } else{ throw new RuntimeException("传入参数为负数"); } } }
@Test public void test2(){ ThrowTest throwTest = new ThrowTest(); throwTest.judge(-100); }
成功抛出异常。
使用try-catch捕获一下异常。
@Test public void test2(){ ThrowTest throwTest = new ThrowTest(); try{ throwTest.judge(-100); } catch (RuntimeException e){ System.out.println(e.getMessage()); } }
如果把throw抛出的异常改为Exception,则直接报错,也就是不能编译。Exception包含两种异常:编译时异常和运行时异常,前者在编译前就要检查是否有可能产生编译时异常;后者是在编译后运行时才会判断的异常。而throw new Exception包含了编译时异常,需要显式处理掉这个异常,怎么处理?try-catch-finally或者throws
class ThrowTest{ private int Number; public void judge(int num) throws Exception{ if(num>=0){ this.Number = num; } else{ throw new Exception("传入参数为负数"); } } }
调用方也要随着进行更改。
@Test public void test2(){ ThrowTest throwTest = new ThrowTest(); try{ throwTest.judge(-100); } catch (RuntimeException e){ System.out.println(e.getMessage()); } catch (Exception e){ System.out.println(e.getMessage()); } }
——自定义异常类
throw还可以抛出自定义异常类。
自定义异常类的声明需要继承于现有的异常体系。
class MyException extends RuntimeException{ static final long serialVersionUID = -703489719076939L; //可以认为是一种标识 public MyException(){} public MyException(String message){ super(message); } }
此时我们可以抛出自定义的异常
class ThrowTest{ private int Number; public void judge(int num) throws MyException{ if(num>=0){ this.Number = num; } else{ throw new MyException("不能输入负数"); } } }
调用者修改
@Test public void test2(){ ThrowTest throwTest = new ThrowTest(); try{ throwTest.judge(-100); } catch (MyException e){ System.out.println(e.getMessage()); } }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!