java基础学习之异常(五)

基本概念

  • 异常的捕获及处理
    • 认识异常
    • 处理异常
    • 异常处理流程
    • throws关键字
    • throw关键字
    • 异常处理标准格式
    • RuntimeException类
    • assert关键字
    • 自定义异常

异常的捕获及处理

认识异常

异常是程序中导致程序中断的一种指令流。
产生异常

// An highlighted block
package com.yootk.demo;
public class Hello{
     
	public static void main(String args[]){
     
		System.out.println("除法计算:" + 10/0);
	}
}
执行结果:Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.company.Main.main(Main.java:6)

在本程序中产生了数学异常,分母不能为0。

处理异常

java针对异常的处理提供了3个核心的关键字:try、catch、finally,利用这3个关键字就可以组成一下异常处理格式。

try{
            //有可能出现异常的语句
        }catch (异常类型   对象){
            //异常处理
        }catch (异常类型   对象){
            //异常处理
        }catch (异常类型   对象){
            //异常处理
        }finally {
            //不管是否出现异常,都要执行的代码
        }

一个完整的异常处理例子

public class Main {
     
    public static void main(String[] args) {
     
	// write your code here
        System.out.println("1、除法计算开始。");
        try {
     
            System.out.println("2、除法计算:" + (10 / 0));// 此处产生异常
            // 异常产生之后的语句将不再执行,此处在try中产生异常,所以下面的输出不会执行
            System.out.println("test");
        } catch (ArithmeticException e) {
     	// 处理算术异常
            e.printStackTrace();	// 输出异常的完整信息
        } finally {
     
            System.out.println("### 不管是否出现异常我都执行!") ;
        }
        System.out.println("3、除法计算结束。");
    }
}

结果:1、除法计算开始。
    java.lang.ArithmeticException: / by zero
    at com.yootk.demo.TestDemo.main(TestDemo.java:7)
    ### 不管是否出现异常我都执行!
     3、除法计算结束。

异常处理流程

异常类结构

ArithmeticException:
java.lang.Object
   |- java.lang.Throwable
      |- java.lang.Exception
         |- java.lang.RuntimeException
            |- java.lang.ArithmeticException


NumberFormatException:
java.lang.Object
   |- java.lang.Throwable
      |- java.lang.Exception
         |- java.lang.RuntimeException
            |- java.lang.IllegalArgumentException
               |- java.lang.NumberFormatException

可以发现所有的异常类型最高的继承类是Throwable,并且通过doc文档可以发现在Throwable下有两个子类:
Error:指的是JVM错误,这个时候的程序并没有执行,无法处理;
Exception:指的是程序运行中产生的异常,用户可以使用异常处理格式处理。

异常处理完整流程

java基础学习之异常(五)_第1张图片
当程序在运行的过程之中出现了异常后,那么会由JVM自动根据异常的类型实例化一个与之类型匹配的异常类对象(此处用户不用去关心如何实例化对象,由JVM负责处理);
产生了异常对象之后会判断当前的语句上是否存在有异常处理,如果现在没有异常处理,那么就交给JVM进行默认的异常处理,处理的方式:输出异常信息,而后结束程序的调用;
如果此时存在有异常的捕获操作,那么会由try语句来捕获产生的异常类实例化对象,而后与try语句后的每一个catch进行比较,如果现在有符合的捕获类型,则使用当前catch的语句来进行异常的处理,如果不匹配,则向下继续匹配其它的catch;
不管最后异常处理是否能够匹配,那么都要向后执行,如果此时程序中存在有finally语句,那么就先执行finally中的代码。但是执行完finally语句后需要根据之前的catch匹配结果来决定如何执行,如果之前已经成功的捕获了异常,那么就继续执行finally之后的代码,如果之前没有成功的捕获异常,那么就将此异常交给JVM进行默认处理(输出异常信息,而后结束程序执行)

throws关键字

thrwos关键字主要是在方法定义上使用的,表示的是此方法之中不进行异常的处理,而交给被调用处处理。

class Math{
     // div方法不处理异常
    public static int div(int x ,int y) throws Exception{
     
        return x/y;
    }
}
public class Main {
     

    public static void main(String[] args) {
     
	// write your code here
        try {
     //div方法抛出异常,必须进行异常处理
            System.out.println(Math.div(10,2));
        }catch (Exception e){
     
            e.printStackTrace();
        }
    }
}

throw关键字

之前的所有异常类对象都是由JVM自动进行实例化操作的,而现在用户也可以自己手工的抛出一个实例化对象(手工调用异常类的构造方法),就通过throw完成了。

public static void main(String args[]) {
     
        try {
     				// 直接抛出了一个自定义的异常类对象
            throw new Exception("自己定义的异常!");
        } catch (Exception e) {
     
            e.printStackTrace();
        }
    }

异常处理标准格式

package com.company;

class Math{
     
    public static int div(int x, int y) throws Exception {
     	// 出现异常要交给被调用处出
        System.out.println("===== 计算开始 =====");// 等价于:资源打开
        int result = 0;
        try {
     	result = x / y; 	// 除法计算
        } catch (Exception e) {
     
            throw e; 	// 向上抛
        } finally {
     
            System.out.println("===== 计算结束 ====="); 	// 等价于:资源关闭
        }
        return result;
    }

}
public class Main {
     

    public static void main(String args[]) {
     
        try {
     
            System.out.println(Math.div(10, 0));// 被调用处处理异常
        } catch (Exception e) {
     
            e.printStackTrace();
        }
    }
}

RuntimeException类

在Java里面为了方便用户代码的编写,专门提供了一种RuntimeException类,这种异常类的最大特征在于:程序在编译的时候不会强制性的要求用户处理异常,用户可以根据自己的需要选择性进行处理,但是如果没有处理又发生了异常了,将交给JVM默认处理。也就是说RuntimeException的子异常类,可以由用户根据需要选择性进行处理。
如果要进行字符串转变为int数据类型,那么可以利用Integer类进行处理,因为在Integer类定义了如下方法:
字符串转换int:public static int parseInt(String s) throws NumberFormatException;

java.lang.Object
|- java.lang.Throwable
  |- java.lang.Exception
     |- java.lang.RuntimeException  → 运行时异常
        |- java.lang.IllegalArgumentException
           |- java.lang.NumberFormatException
public class Main {
     
    public static void main(String args[]) {
     
        int temp = Integer.parseInt("100");// 直接将字符串变为int型
        System.out.println(temp);
    }
}

assert关键字

assert关键字是在JDK 1.4的时候引入的,其主要的功能是进行断言。断言指的是程序执行到某行之后,其结果一定是预期的结果。

 public class Main {
     
    public static void main(String args[]) {
     
        int num = 10;
        // 假设中间可能经过了20行代码来操作num的内容,期望中的内容应该是20
        assert num == 20 : "num的内容不是20";// 进行断言操作
        System.out.println("num = " + num);
    }
}

本程序中使用了断言进行操作,很明显程序中断言的判断条件并不满足,但是依然没有任何的错误产生,这是因为Java默认情况下是不开启断言的。如果要想启用断言,则应该增加一些选项:
java -ea com.yootk.demo.TestDemo
而增加“-ea”参数之后,本程序就会出现如下的错误信息:
Exception in thread “main” java.lang.AssertionError: num的内容不是20

自定义异常

Java本身已经提供了大量的异常,但是这些异常在实际的工作之中往往并不够去使用,例如:当你要执行数据增加操作的时候,有可能会出现一些错误的数据,而这些错误的数据一旦出现就应该抛出异常,例如:AddException,但是这样的异常Java并没有,所以就需要由用户自己去开发一个自己的异常类。如果要想实现自定义异常类,只需要继承Exception(强制性异常处理)或RuntimeException(选择性异常处理)父类即可。

class AddException extends Exception {
     			// 此异常类要强制处理
    public AddException(String msg) {
     
        super(msg);		// 调用父类构造
    }
}
public class Main {
     
    public static void main(String args[]) {
     
        int num = 20;
        try {
     
            if (num > 10) {
      	// 出现了错误,应该产生异常
                throw new AddException("数值传递的过大!");
            }
        } catch (Exception e) {
     
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(JavaSE,java)