• Java基础-day17


    异常处理和文本I/O

    Java 可以让一个方法可以抛出一个异常 ,该异常可以被调用者捕获和处理 。

    try-throw-catch

    import java.util.Scanner;
    
    public class QuotientWithException {
        public static int quotient(int number1, int number2){
            if(number2 == 0)
                throw new ArithmeticException("Divisor cannot be zero");
            return number1 / number2;
        }
    
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            System.out.println("Enter two integers:");
            int number1 = input.nextInt();
            int number2 = input.nextInt();
    
            try {
                int result = quotient(number1, number2);
                System.out.println(number1 + " / " + number2 + " = " + result);
            }
    
            catch (ArithmeticException ex){
                System.out.println("Exception: an integer " +
                        "cannot be divided by zero ");
            }
            System.out.println("Execution continues...");
        }
    }
    
    Enter two integers:
    5 0
    Exception: an integer cannot be divided by zero 
    Execution continues...
    
    Enter two integers:
    3 2
    3 / 2 = 1
    Execution continues...
    

    语句

    throw new ArithmeticException("Divisor cannot be zero");
    
    1. 通过异常类java.lang.ArithemeticException创建一个异常类对象,从而抛出异常
    2. 当异常抛出后,正常的执行流程被中断
    3. 抛出异常就是将异常从一个地方传递到另一个地方
    4. try 块包含了正常情况下执行的代码
    5. 异常被catch 块所捕获 。 catch块中的代码执行以处理异常
    6. throw 语句类似于方法的调用 , 但不同于调用方法的是
      • 它调用的是 catch 块
      • 在执行完 catch 块之后 , 程序控制不返回到 throw 语句;而是执行 catch 块后的下一
        条语句

    异常处理最根本的优势就是将检测错误(由被调用的方法完成)从处理错误(由调用方法完成)中分离出来 。

    很多库方法都会抛出异常

    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class InputMismatchExceptionDemo {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            boolean continueInput = true;
    
            do {
                try {
                    System.out.println("Enter an integer:");
                    int number = input.nextInt();
                    System.out.println("The number entered is " + number);
                    continueInput = false;
                }
                catch (InputMismatchException ex){
                    System.out.println("Try again.");
                    input.nextLine();       // 丢弃当前输入行
                }
    
            }while (continueInput);
        }
    }
    
    
    Enter an integer:
    3.00
    Try again.
    Enter an integer:
    0
    The number entered is 0
    

    异常类型

    异常是对象 , 而对象都采用类来定义 。 异常的根类是 java.lang.Throwable

    Snipaste_2020-04-22_14-28-27

    Throwable类是所有异常类的根 。 所有的 Java 异常类都直接或者间接地继承自Throwable 。 可以通过继承 Exception 或者 Exception 的子类来**创建自己的异常类 **

    RuntimeExceptionError 以及它们的子类都称为免检异常 ( unchecked exception ) 。 所有其他异常都称为必检异常 ( checked exception ) , 意思是指编译器会强制程序员检査并通过 try - catch 块处理它们 , 或者在方法头进行声明

    关于异常处理的更多知识

    Java异常处理的三种操作:

    1. 声明一个异常
    2. 抛出一个异常
    3. 捕获一个异常

    Snipaste_2020-04-22_14-37-59

    声明异常

    方法要拋出的其他异常都必须在方法头中显式声明 , 这样 , 方法的调用者会被告知有异常

    public void myMethod() throws IOException
    

    关键字 throws 表明 myMethod 方法可能会抛出异常IOException。如果方法可能会抛出多个异常, 就可以在关键字 throws 后添加一个用逗号分隔的异常列表

    public void myMethod()
        throws Exception1, Exception2, ..., ExceptionN
    

    如果方法没有在父类中声明异常 , 那么就不能在子类中对其进行继承来声明异常

    抛出异常

    检测到错误的程序可以创建一个合适的异常类型的实例并抛出它 , 这就称为抛出一个异常。假如程序发现传递给方法的参数与方法的合约不符 ( 例如 , 方法中的参数必须是非负的 , 但是传入的是一个负参数 ) , 这个程序就可以创建 IllegalArgumentException 的一个实例并抛出它

    IllegalArgumentException ex = 
        new IllegalArgumentException("Wrong Argument");
    throw ex;
    或者表示为:
        
    throw new IllegalArgumentException("Wrong Argument");
    

    捕获异常

    当抛出一个异常时 , 可以在try - catch块中捕获和处理它

    try{
        statements;
    }
    catch(Exception1 exVar1){
        handler for exception1;
    }
    catch(Exception2 exVar2){
        handler for exception2;
    }
    ...
    catch(ExceptionN exvarN){
        handler for exceptionN;
    }
    

    如果在执行 try 块的过程中没有出现异常 , 则跳过 catch 子句

    如果 try 块中的某条语句抛出一个异常 , Java 就会跳过 try 块中剩余的语句 , 然后开始査找处理这个异常的代码的过程

    Snipaste_2020-04-22_15-07-06

    Snipaste_2020-04-22_15-07-16

    注意

    1. 从一个通用的父类可以派生出各种异常类 。 如果一个 catch 块可以捕获一个父类的异常对象,它就能捕获那个父类的所有子类的异常对象 。
    2. 在 catch 块中异常被指定的顺序是非常重要的。 如果父类的 catch 块出现在子类的catch 块之前 , 就会导致编译错误
    Snipaste_2020-04-22_15-11-30
    1. Java 强迫程序员处理必检异常
    Snipaste_2020-04-22_15-15-28
    1. 对于使用同样的处理代码处理多个异常的情况 , 可以使用新的 JDK 7 的多捕获特征( multi - catch feature ) 简化异常的代码编写
    catch(Exception1|Exception2|...|ExceptionN ex){ // 如果其中一个异常被捕获,则执行处理的代码
        // Same code for handling these exceptions;	
    }
    

    从异常中获取信息

    可以利用下面这些java.lang.Throwable类中的实例方法获取有关异常的信息

    Snipaste_2020-04-22_15-45-00

    实例

    Snipaste_2020-04-22_15-54-54Snipaste_2020-04-22_15-55-01

    Snipaste_2020-04-22_15-55-17

    finally子句

    无论异常是否产生 , finally 子句总是会被执行的

    try{
        statements;
    }
    catch(TheException ex){
        handling ex;
    }
    finally{
        finalStatements;
    }
    
    Snipaste_2020-04-22_16-17-35

    何时使用异常

    当错误需要被方法的调用者处理的时候 , 方法应该抛出一个异常 。

    try 块包含正常情况下执行的代码 。 catch 块包含异常情况下执行的代码 。 异常处理将错误处理代码从正常的程序设计任务中分离出来 , 这样 , 可以使程序更易读 、 更易修改

    不要用 try - catch 块处理简单的 、 可预料的情况

    重新抛出异常

    如果异常处理器不能处理一个异常 , 或者只是简单地希望它的调用者注意到该异常 , Java 允许该异常处理器重新抛出异常 。

    Snipaste_2020-04-22_16-27-30

    链式异常

    catch 块重新抛出原始的异常 。 有时候,可能需要同原始异常一起抛出一个新异常(带有附加信息), 这称为链式异常

    Snipaste_2020-04-22_16-34-20

    main方法调用 method1()( 第 4 行 ), method1调用 method2 ( 第 13 行 ) , method2 拋出一
    个异常 ( 第 21 行 ) 。 该异常被 method1的 catch 块所捕获 , 并在第 16 行被包装成一个新异
    常 。 该新异常被抛出 , 并在 main 方法中的 catch 块中被捕获 ( 第 6 行 ) 。 示例输出在第 7 行中 printStackTrace() 方法的结果 。 首先 , 显示从 method1中抛出的新异常 , 然后显示从
    method 2 中抛出的原始异常

    创建自定义异常类

    可以通过派生 java.lang.Exception 类来定义一个自定义异常类

    Snipaste_2020-04-22_16-49-06

    要创建一个InvalidRachusExMption类 , 必须传递一个半径 。

    Snipaste_2020-04-22_16-50-24

    Write by Gqq

  • 相关阅读:
    JavaScript语言精粹_第二章
    java并发Executors学习笔记
    iOS开发响应者链触摸事件
    快速学会Spring动态代理原理
    iOS类别Category与扩展Extension
    几款iOS开发常用工具
    Java回调接口的理解
    零基础学iPhone开发
    Java中的多线程
    Java文件下载的几种方式
  • 原文地址:https://www.cnblogs.com/zgqcn/p/12820910.html
Copyright © 2020-2023  润新知