码迷,mamicode.com
首页 > 其他好文 > 详细

异常处理

时间:2019-04-26 22:55:36      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:cell   turn   test   计算   一起   win   问题   完全   name   

1   异常处理

1.1   传统处理异常的方式

public class Test01 {

     public static void main(String[] args) {

         Scanner sc = new Scanner(System.in);

         System.out.println("请输入第一个数:");

        

         int num1 = 0;

         if(sc.hasNextInt()) {           

              num1 = sc.nextInt();

             

              System.out.println("请输入第二个数:");

              int num2 = 0;

              if(sc.hasNextInt()) {

                   num2 = sc.nextInt();

                  

                   if(0 == num2) {

                       System.out.println("除数不能为0!");

                   }else {                    

                       int r = num1 / num2;

                       System.out.println("num1/num2 = "+r);

                   }

 

              }else {

                   System.out.println("第二个数输入不是数字");

              }

             

         }else {

              System.out.println("第一个数输入不是数字!");

         }

     }

}

缺点:

[1] 通过判断影响执行效率。

[2] 判断逻辑和业务逻辑交织在一起,可维护性很差。

 

 

 

 

1.2   异常

异常是指在程序的运行过程中所发生的不正常的情况,它会中断正在运行的程序

 

异常处理机制

java中通过异常处理机制为程序提供异常处理的能力,保持程序继续运行而不中断!

 技术图片

 

 

1.3   异常处理

涉及异常处理的关键字有try…catch/try…catch…finally

 

1.3.1     try/catch

把有可能产生异常的代码放到try代码块中,catch代码块负责捕获并处理异常。

 

[1]正常执行,没出现任何异常

 技术图片

 

 

[2]出现异常,异常处理,正常结束

 技术图片

 

 

Exception是所有异常类的直接或者间接父类。

异常常见方法

 

printStackTrace:打印异常的执行堆栈信息

java.util.InputMismatchException

     at java.util.Scanner.throwFor(Scanner.java:864)

     at java.util.Scanner.next(Scanner.java:1485)

     at java.util.Scanner.nextInt(Scanner.java:2117)

     at java.util.Scanner.nextInt(Scanner.java:2076)

     at cn.sxt02.exception02.Test01.main(Test01.java:14)

 

一般而言,异常堆栈信息很多,开发者只需要看懂

第一行:异常简单信息(异常类型,异常的描述等)

最后一行:异常出现的位置(类->方法->方法具体的行)

在控制台中异常堆栈信息输出位置不固定

 

getMessage:返回异常的描述信息

 

package cn.sxt02.exception02;

import java.util.Scanner;

public class Test01 {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        System.out.println("请输入第一个数:");

 

        int num1 = 0;

        int num2 = 0;

       

        try {

            num1 = sc.nextInt();

 

            System.out.println("请输入第二个数:");

            num2 = sc.nextInt();

 

            int r = num1 / num2;

            System.out.println("num1/num2 = " + r);

        }catch (Exception e) {

            System.out.println("程序出现异常");

            // 打印异常的信息

            // System.out.println(e.toString());

           

           

            // 打印异常堆栈信息

             e.printStackTrace();

           

            // 返回异常的描述信息,如果没有信息,返回null(InputMismatchException 没有描述信息)

            System.out.println(e.getMessage());

        }

       

        System.out.println("程序正常结束");

    }

}

 

 

[3]异常类型不匹配

 技术图片

 

 

[4] 多重catch

public class Test03 {

     public static void main(String[] args) {

         Scanner sc = new Scanner(System.in);

         System.out.println("请输入第一个数:");

 

         int num1 = 0;

         int num2 = 0;

        

         try {

              num1 = sc.nextInt();

 

              System.out.println("请输入第二个数:");

              num2 = sc.nextInt();

 

              int r = num1 / num2;

              System.out.println("num1/num2 = " + r);

         }catch (ArithmeticException e) {

              System.out.println("数学计算异常:"+e.getMessage());

         }catch(InputMismatchException e) {

              System.out.println("输入不匹配异常:"+e.getMessage());

         }catch (Exception e) {

              System.out.println("发送异常:"+e.getMessage());

         }

        

         System.out.println("程序正常结束");

     }

}

 

1.3.2     try/catch/finally

把有可能产生异常的代码放到try中,catch负责匹配并处理异常,finally块用于进行收尾工作(关闭数据库、关闭文件、释放内存等资源)

 

不管是否发生异常,finally都执行。

public static void main(String[] args) {

         Scanner sc = new Scanner(System.in);

         System.out.println("请输入第一个数:");

 

         int num1 = 0;

         int num2 = 0;

 

         try {

              num1 = sc.nextInt();

 

              System.out.println("请输入第二个数:");

              num2 = sc.nextInt();

 

              int r = num1 / num2;

              System.out.println("num1/num2 = " + r);

         } catch (Exception e) {

              System.out.println("程序出现异常");

         } finally {

              System.out.println("不管是否出现异常,finally都执行");

         }

 

         System.out.println("程序正常结束");

     }

 

finally 总是执行,常用进行收尾类工作。

 

特殊情况(B)

[1] finally不执行的情况。

System.exit(0) 正常推出jvm,finally不会执行。

 

[2]catch可以省略,变成try…finally块。

1.3.3     return

存在return的try/catch/finally执行顺序

package cn.sxt02.exception03;

 

/**

 * 存在return的情况

 */

public class Test02 {

 

     public static int div(int a, int b) {

 

         try {

              int r = a / b;

              return r;

 

         } catch (Exception e) {

              System.out.println("出现异常");

 

              return 0;

 

         } finally {

              System.out.println("我是finally");

         }

 

     }

 

     public static void main(String[] args) {

 

         int r = Test02.div(10, 0);

         System.out.println("r=" + r);

         System.out.println("程序正常结束");

     }

}

 

 

1.4  异常的分类

技术图片

 

技术图片

Throwable 类是 Java 语言中所有错误(Error)或异常(Exception)的父类,只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。

 

Error 类表示错误类。仅靠程序本身无法恢复的严重错误。jvm内存耗尽、jvm崩溃等。

Exception 类表示异常类,可以通过java 异常处理机制处理。

 

Exception 根据是否处理分为两种情况。

RuntimeException:运行时异常。不要求程序必须做出处理。是所有运行时异常的父类。

CheckedException:检查时异常。要求程序必须处理,不处理编译不通过。

 

public class Test01 {

     public static void main(String[] args) {

         // 运行时异常

         Scanner sc = new Scanner(System.in);

         // runtime exception

         int r = sc.nextInt();

         System.out.println("r = "+ r);

        

         // 检查时异常

         SimpleDateFormat df = new SimpleDateFormat();

         try {

              Date date = df.parse("2019");

         } catch (ParseException e) {

              e.printStackTrace();

         }

     }

}

 

常见的运行时异常

ArithmeticException:数学计算异常。比如除数为0

InputMismatchException:输入不匹配异常

ArrayIndexOutofBoundsException:数组下标越界异常。

NullPointException:空指针异常,对象没有初始化就使用时,jvm会抛出该异常

IllegalArgumentException:非法参数异常。

ClassCastException:强制类型转换异常。

NumberFormatException:数字格式化异常。比如把“abc”格式化成数字。

 

常见的检查时异常:

ClassNotFoundException:类没有被发现异常。

SQLException:数据库相关异常
IOException:IO操作异常
ParseException:解析错误异常
FileNotFoundException:文件未发现异常。
 
运行时异常和检查时异常的区别

运行时异常:包括RuntimeException及其所有子类。不要求程序必须对它们作出处理,比如InputMismatchException、ArithmeticException、NullPointerException等。即使没有使用try-catch或throws进行处理,仍旧可以进行编译和运行。如果运行时发生异常,会输出异常的堆栈信息并中止程序执行。

Checked异常(非运行时异常):除了运行时异常外的其他异常类都是Checked异常。程序必须捕获或者声明抛出这种异常,否则出现编译错误,无法通过编译。处理方式包括两种:通过try-catch捕获异常,通过throws声明抛出异常从而交给上一级调用方法处理

 

1.5   声明异常

1.5.1     throws关键字

当一个方法可能存在异常,而此时自身又无法更好的处理,可以交给外界处理。此时用throws声明并抛出异常。

public class Test01 {

 

     public static int div(int a, int b) throws ArithmeticException{

         int r = 0;

         r = a / b;

         return r;

     }

 

     public static void main(String[] args) {

         try {

              Test01.div(10, 0);

         } catch (ArithmeticException e) {

              System.out.println("除数不能为0");

         }

     }

}

 

开发者可以根据需要声明检查时异常(Exception或者非运行时异常)和运行时异常(RuntimeException或其子类)

 

如果调用处也不知道如何处理异常,可选择继续声明异常,我们把这个过程称为异常上抛。

public class Test01 {

 

    public static int div(int a, int b) throws Exception{

        int r = 0;

        r = a / b;

        return r;

    }

 

    public static void main(String[] args) throws Exception{

       

        //【1】 调用处知道如何处理!

        /*

        try {

            Test01.div(10, 0);

        } catch (Exception e) {

            e.printStackTrace();

        }

        */

       

        // 【2】调用处也不知道如何处理

        Test01.div(10, 0);

       

    }

}

 

1.5.2     声明异常和重载的关系

声明异常和重载没有任何关系

 

public class Test01 {

 

    public static int div(inta, intb) throws Exception{

        int r = 0;

        r = a / b;

        return r;

    }

   

    public static int div(inta, intb) {

        int r = 0;

        r = a / b;

        return r;

    }

}

 

方法重载

[1]方法名相同
[2]参数列表不同(个数、类型、顺序)

[3]和返回值、修饰符、声明异常无关。

1.5.3     声明异常和重写的关系

声明一个和方法重写有关系。

 

[1]父类方法声明了异常(检测时或运行时),子类可以不声明任何异常。

public class Father {

 

     public void showInfo() throws Exception{

        

     }

}

 

public class Son extends Father{

    

     @Override

     public void showInfo(){

        

     }

    

}

 

可以认为:父类方法抛出异常,子类在重写过程中把该异常处理掉了,所以子类方法不用声明异常。

 

[2] 父类方法声明没有声明任何异常(检测时或运行时),子类也不声明异常或者声明运行时异常。

public class Father {

 

     public void showInfo(){

        

     }

}

public class Son extends Father{

    

     @Override

     public void showInfo() throws Exception{

        

     }

    

}

 

[3] 父类声明了异常(检测时或运行时),子类声明完全一样的异常。

public class Father {

 

     public void showInfo() throws Exception{

        

     }

}

public class Son extends Father{

   

    @Override

    public void showInfo() throws Exception {

       

    }

   

}

 

1.6   手动抛出异常

1.6.1     throw

除了系统自动抛出异常外,有些问题需要开发者手动抛出异常。使用关键字throw

 

package cn.sxt02.exception06;

 

public class Student {

     private String name;

     private String gender;

 

     public String getName() {

         return name;

     }

 

     public void setName(String name) {

         this.name = name;

     }

 

     public String getGender() {

         return gender;

     }

 

     public void setGender(String gender) throws Exception{

         if(gender.equals("男") || gender.equals("女")) {        

              this.gender = gender;

         }else {

              throw new Exception("性别不合法!");

         }

     }

 

     public Student(String name, String gender) {

         super();

         this.name = name;

         this.gender = gender;

     }

 

     public Student() {

         super();

     }

    

}

 

public class Test01 {

     public static void main(String[] args){

         Student stu = new Student();

         stu.setName("二狗");

         try {

              stu.setGender("xxx");

         } catch (Exception e) {

              System.out.println(e.getMessage());

         }

     }

}

 

1.6.2     自定义异常

如果开发者需要手动抛出的异常在系统不存在,可以自定义异常。

如果要自定义异常,首先要确定异常类型,如果异常是运行时异常,必须继承RuntimeException或其子类;如果异常是检查时异常,必须继承Exception或其子类。

 

异常的命名方式,参考系统命名方式,以Exception结尾。

 

public class AgeException extends Exception{

 

     public AgeException() {

         super();

     }

 

     public AgeException(String message) {

         super(message);

     }

    

}

异常处理

标签:cell   turn   test   计算   一起   win   问题   完全   name   

原文地址:https://www.cnblogs.com/l3344/p/10776779.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!