zoukankan      html  css  js  c++  java
  • Java基础——详尽说明try-catch-finally的用法

    问:Java异常处理机制,理解了吗?Java异常处理,真的掌握了吗?什么是自定义异常?catch体里遇到return 是怎么处理?finally 体里有return怎么处理?catch 和 finally 体里同时遇上 return 怎么办?几道例题,理清它们。

    try catch语句

    格式:(代码区如果有错误,就会返回到异常处理)

    1 try{
    2 
    3 //代码区
    4 
    5 }catch(Exception e){
    6 
    7 //异常处理
    8 
    9 }

    首先要清楚,异常有运行时异常和check异常:

    运行异常不需要强制捕获,他们是RuntimeException的子类。check异常需要try、catch的异常处理。

    可以调用API去查询一下,比如常见的RuntimException有IndexOUtOfBoundsException(索引过界)、NullpointerException(空指针异常)等。常见的check异常有IO异常、SQL异常、FileNotFoundException(日期转换异常)等。

    严重的话,如果某个高频率访问的类没有try,出现异常会导致程序崩溃。而try则可以保证程序的正常运行下去,比如说:

    1 try{
    2 int i = 1/0;
    3 }catch(Exception e){
    4 .....
    5 }

    小到一个计算,如果除数为0,则会报错,如果没有try的话,程序直接挂掉。用try的话,则可以让程序运行下去,并且输出为什么出错!

    try catch 是捕捉try部分的异常,当你没有try catch的时候,如果出现异常则程序报错,加上try catch,出现异常程序正常运行,只是把错误信息存储到Exception里,所以catch是用来提取异常信息的,你可以在Catch部分加上一句System.out.println(e.ToString());,如果出现异常可以把异常打印出来。

    代码实例:

     1 public class TestEx1 {
     2     public int add(int a, int b) {
     3         return a + b;
     4     }
     5 
     6     public int dev(int a, int b) {
     7         int c = a / b;// 这里有隐患
     8         return c;
     9     }
    10 
    11     public static void main(String[] args) {
    12         TestEx1 c = new TestEx1();
    13         int result = c.add(4, 9);
    14         System.out.println("求和的结果是" + result);
    15         try { // 防患于未然
    16             int result_chu = c.dev(90, 0);
    17             System.out.println("除的结果是" + result_chu);
    18         } catch (Exception e) {
    19             System.out.println("出错啦~");
    20 
    21         }
    22     }
    23 }

     下面补充一下,今天做的几道例题。笔记在注释里面了,要记住。

    例一:

     1 public class TestEx2 {
     2     public int add(int a, int b) {
     3         return a + b;
     4     }
     5 
     6     public int dev(int a, int b) throws Exception {
     7         int c = a + b;
     8         return c;
     9     }
    10 
    11     static void main(String[] args) {
    12         TestEx2 c = new TestEx2();
    13         int result = c.add(7, 9);
    14         System.out.println("求和的结果是" + result);
    15         try {
    16             int result_chu = c.dev(90, 0);
    17             System.out.println("除的结果是" + result_chu);
    18         } catch (Exception e) {
    19             e.printStackTrace();
    20         }
    21     }
    22 }

    例二:

    1 public class TestEx3 {
    2     public static void main(String[] args) throws Exception {
    3         throw new Exception("我是扔着玩的");
    4     }
    5 }

    例三:

     1 public class TestEx4 {
     2     public int add(int a, int b) {
     3         return a + b;
     4     }
     5 
     6     // 假设这个除法的除数和被除数都不能为零
     7     public int dev(int a, int b) throws Exception {
     8         if (a == 0) {
     9             throw new Exception("除数不能为零");
    10         } else if (b == 0) {
    11             throw new Exception("被除数也不能为零");
    12         }
    13         int c = a / b;
    14         return c;
    15     }
    16 
    17     public static void main(String[] args) {
    18         TestEx4 t = new TestEx4();
    19         int result_add=t.add(4,80);
    20         System.out.println("结果是:" + result_add);
    21         
    22         try {
    23             //int result_add=t.add(4,80);加法写在try-catch里面,将不能执行
    24             int result = t.dev(0, 90);
    25             System.out.println("结果是:" + result);
    26             //System.out.println("结果是:" + result_add);加法写在try-catch里面,将不能执行
    27         } catch (Exception e) {
    28             e.printStackTrace();
    29         }
    30         
    31         System.out.println("执行到这里就是完美了");
    32     }
    33 }

    例四:

     1 import java.util.Date;
     2 
     3 //自定义异常:自定义一个类,继承字Eception类,附Eception 继承自Throwable
     4 public class TestEx5 extends Exception {
     5     /**
     6      * 
     7      */
     8     private static final long serialVersionUID = 1L;
     9     private String m;
    10 
    11     public TestEx5(String m) {
    12         super();// 调用父类的构造函数,这是一个好的习惯。注意:s是小写的。
    13         this.m = m;
    14     }
    15 
    16     public void printErrorInfo() {
    17         System.out.println("错误的信息:" + m + "	" + new Date());
    18     }
    19 
    20     public void log() {
    21         System.out.println("信息已经写在日志上了");
    22     }
    23 
    24     // 虚拟一个银行业务
    25     public static class Bank { //要用static修饰一下,否则下面调用的时候,会提示“Bank类没有封闭实例访问类型”
    26         /*
    27          * Java里面static一般用来修饰成员变量或函数。
    28          * 但有一种特殊用法是用static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以。
    29          * 被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。
    30          * 
    31          */
    32         int money = 90000;
    33 
    34         public void saveMoney(int money) {
    35             this.money += money;
    36             System.out.println("业务办理成功" + "	" + "存款为" + money + "元");
    37         }
    38 
    39         /*
    40          * 需求:设置为,每次取钱最多不能超过50000,超了就抛出异常
    41          *  取钱后,余额不能低于2,如果低于2就抛出异常
    42          */
    43         public void getMoney(int money) throws TestEx5 {
    44             if (money > 50000) {
    45                 throw new TestEx5("取款金额最大不能超过50000");
    46             } else if (this.money - money < 2) {
    47                 throw new TestEx5("余额不足!");
    48             } else {
    49                 this.money -= money;
    50                 System.out.println("业务办理成功,本次取款金额为" + money + "元");
    51                 System.out.println("当前余额" + this.money + "元");
    52             }
    53         }
    54     }
    55 
    56         public static void main(String[] args) {
    57             Bank bank = new Bank();
    58             bank.saveMoney(30000);
    59             bank.saveMoney(20000);
    60             try { // 取钱有界限,所以用try-catch把它包裹起来,并制定规约,超出就抛出异常
    61                 bank.getMoney(20000);
    62                 bank.getMoney(30000);
    63                 bank.getMoney(20000);
    64                 bank.getMoney(20000);
    65                 bank.getMoney(200000);
    66             } catch (TestEx5 e) {// 调用自己定义的超出异常
    67                 e.log();
    68                 e.printErrorInfo();
    69                 e.printStackTrace();
    70             }
    71         }
    72     }

    结果:

    例五:

     1 import java.io.FileWriter;
     2 import java.io.Writer;
     3 
     4 /*
     5  * 请说明一下finally、final、finalize三者的区别:
     6  *1.final:用来定义常量的关键字,修饰方法表示不能重写;修饰类表示不能继承;修饰变量表示值不能改变
     7  *2.finalize:是Object类提供的一个方法,在类被垃圾回收器回收的时候调用,system.gc();可以引起到垃圾回收的调用
     8  *3.finally:用于处理异常,表示代码出不出异常都要执行。(也有两种特殊的情况,会使得finally执行不到)
     9  */
    10 public class TestEx6 {
    11 public static void main(String[]args){
    12     try{
    13         Writer t=new FileWriter("c:/txt");//快捷键 ctrl+shift+o:直接引入导包
    14         t.write("这是我用eclipse直接在c盘建立的一个文本");//注意这里不是Writer,没有r。
    15         t.close();
    16         /*
    17          *关闭资源,Java本身不具备打开和关闭文件的功能,具备这个功能的往往是操作系统。关闭是个好习惯,如果不进行关闭,操作系统还将继续对他进行占有。
    18          *这时再去试图打开或者删除此文件是不成功的。所用要用到.close();。
    19          */
    20         }catch(Exception e){
    21             e.printStackTrace();
    22         }
    23     System.out.println("执行到这里就是胜利");
    24 }
    25 }

    例六:

     1 import java.io.FileWriter;
     2 import java.io.IOException;
     3 import java.io.Writer;
     4 
     5 public class TestEx7 {
     6     /*
     7      * J2SE 提供的最后一个批注是 @SuppressWarnings。
     8      * 该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。
     9      * 
    10      * @SuppressWarnings 批注允许您选择性地取消特定代码段(即,类或方法)中的警告。
    11      * 其中的想法是当您看到警告时,您将调查它,如果您确定它不是问题,您就可以添加一个 @SuppressWarnings 批注,以使您不会再看到警告。
    12      * 虽然它听起来似乎会屏蔽潜在的错误,但实际上它将提高代码安全性,因为它将防止您对警告无动于衷 — 您看到的每一个警告都将值得注意。
    13      */
    14 
    15     public static void main(String[] args) {
    16         Writer t = null;//這里定義了一個全局變量
    17         try {
    18 
    19             t = new FileWriter("c:/1.txt");//上面定義了全局變量t,這里的Writer t=new FileWriter("c:/1.txt");中等號左邊的Writer要去掉。
    20             t.write("这是加入的一个文本");// 注意这里不是Writer,没有r。
    21         } catch (IOException e) {
    22             // TODO Auto-generated catch block
    23             e.printStackTrace();
    24         } finally {// finally里面可以有try-catch语句
    25             try {
    26                 t.close();
    27             } catch (IOException e) {
    28                 // TODO Auto-generated catch block
    29                 e.printStackTrace();
    30             }
    31         }
    32         System.out.println("會執行到這里嗎?");
    33     }
    34 }

    总结:

    1.java的异常处理中,在不抛出异常的情况下,程序执行完try里面的代码块之后,该方法并不会立即结束,而是继续试图去寻找该方法有没有finally的代码块,如果没有finally代码块,整个方法在执行完try代码块后返回相应的值来结束整个方法。

    2.值得注意的是,如果有finally代码块,此时程序执行到try代码块里的return语句之时并不会立即执行return,而是先去执行 finally 代码块里的代码,此时又分为两种情况,若 finally 代码块里没有return或没有能够终止程序的代码,程序将在执行完finally代码块代码之后再返回try代码块执行return语句来结束整个方法;若finally代码块里有return或含有能够终止程序的代码,方法将在执行完finally之后被结束,不再跳回 try 代码块执行 return。

    3.finally里的语句只有两种情况下,会不被执行。一种是,在try-catch语句之前,程序就结束了或者挂掉了。第二种是遇到System.exit();

    补充说明System.exit();的用法:

    System是一个Java类,调用exit(0)方法终止虚拟机也就是退出你的Java程序,括号里面的是参数,进程结束的返回值。

    查看Java.lang.System的源代码,我们可以找到System.exit(status)这个方法的说明,代码如下:

     1     /** 
     2        * Terminates the currently running Java Virtual Machine. The 
     3        * argument serves as a status code; by convention, a nonzero status 
     4        * code indicates abnormal termination. 
     5        * <p> 
     6        * This method calls the <code>exit</code> method in class 
     7        * <code>Runtime</code>. This method never returns normally. 
     8        * <p> 
     9        * The call <code>System.exit(n)</code> is effectively equivalent to 
    10        * the call: 
    11        * <blockquote><pre> 
    12        * Runtime.getRuntime().exit(n) 
    13        * </pre></blockquote> 
    14        * 
    15        * @param      status   exit status. 
    16        * @throws  SecurityException 
    17        *        if a security manager exists and its <code>checkExit</code> 
    18        *        method doesn't allow exit with the specified status. 
    19        * @see        java.lang.Runtime#exit(int) 
    20        */  
    21       public static void exit(int status) {  
    22     untime.getRuntime().exit(status);  
    23       }  

    此方法是用来结束当前正在运行中的java虚拟机:

    1.System.exit(0)是将整个虚拟机里的内容都停掉了 ;

    2.dispose()只是关闭这个窗口,但是并没有停止整个application exit() ;

    3.System.exit(0)是正常退出程序,而System.exit(1)或者说非0表示非正常退出程序;

    4.System.exit(status)不管status为何值都会退出程序。和return 相比有以下不同点:return是回到上一层,而System.exit(status)是回到最上层。

  • 相关阅读:
    Django踩坑记录2
    Django踩坑记录1
    pycharm2020激活破解和汉化
    python 读写文件
    python截取视频制作动态表情包+文字
    jenkins运行错误解决办法
    python读取xlsx文件
    python读取csv文件
    python+requests之接口测试
    win10安装jenkins忘记密码的解决方法
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/7051207.html
Copyright © 2011-2022 走看看