41--异常处理机制

认识异常:

异常就是在程序运行过程中所发生的不正常事件,如:找不到文件,运算错误(除数为零)、数组越界、加载一个不存在的类、对null对象进行操作、类型转换错误等。异常会中断程序的运行。
首先从一个实例了解下异常:
实例:编写一个程序实现根据输入的除数和被除数,计算出商,最后输出"感谢你使用本程序"

public class Test {
    
    
	/**异常代码演示
	 * @param args
	 */
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		Scanner  input= new Scanner(System.in);
		System.out.println("请输入一个除数:");
		int num1=input.nextInt();
		System.out.println("请输入除数:");
		int num2=input.nextInt();
		System.out.println(String.format("%d/%d=%d", num1, num2,num1/num2));
		System.out.println("感谢使用本程序!");
	}
}

思考一下几个问题:

  1. 在正常情况下,输入的结果正确无误
  2. 当被除数或除数输入不是整数时,是不是有异常抛出?
  3. 当被除数输入0时,程序也会发生异常,出现了这种异常我们该怎么去做呢?
    首先想到是不是可以通过判断选择结构呢?
    实例:
public class ExceptionDemo {
    
    
	public static void main(String[] args) {
    
    
		Scanner input= new Scanner(System.in);
		System.out.println("输入被除数:");
		int num1=0;//定义变量用来保存输入的被除数
		if(input.hasNextInt()){
    
    //判断输入的数值是不是整数
			num1=input.nextInt();
		}else{
    
    //如果输入的不是整数
			System.err.println("输入的不是整数,程序将退出");
			System.exit(2);
		}
		
		System.out.println("请输入除数:");
		int num2=0;
		if(input.hasNextInt()){
    
    //判断输入的数值是不是整数
			num2=input.nextInt();
			if(0==num2){
    
    //判断是不是0
				System.err.println("输入的除数是0,程序退出");
				System.exit(2);
			}
		}else{
    
    
			System.err.println("输入的除数不是整数,程序退出");
			System.exit(2);
		}
		System.out.println(String.format("%d/%d=%d", num1, num2,num1/num2));
		System.out.println("感谢使用本程序!");
	}
}

总结:
通过if-else语句处理异常的缺点:

  1. 代码臃肿
  2. 程序员把大量的精力用在处理异常上,开发效率低下
  3. 很难找出所用的异常
  4. 异常和业务代码交织在一起维护性难度大
    此时我们就可以使用异常处理机制,对上面的问题进行解决。

异常概念:

异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。 (开发过程中的语法错误和逻辑错误不是异常)
Java程序在执行过程中所发生的异常事件可分为两类:
1.**Error:**Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源 耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性 的代码进行处理
实例:

public class ErrorTest {
    
    
	public static void main(String[] args) {
    
    
		//1.栈溢出:java.lang.StackOverflowError
//		main(args);
		//2.堆溢出:java.lang.OutOfMemoryError 
		Integer[] arr = new Integer[1024*1024*1024];
		
	}
}

一般情况下,我们对此类错误不做代码上的补救。
2.Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使 用针对性的代码进行处理。
例如: 1).空指针访问
2)试图读取不存在的文件
3)网络连接中断
4)数组角标越界
处理此类异常常用的5个关键字:

  1. try:执行可能产生异常的代码
  2. catch:捕获异常,一旦try中的代码出现异常,在此进行捕获处理
  3. finally:无论是否产生异常,该语句块都会执行
  4. throw :手动抛出异常
  5. throws:声明方法可能要抛出的异常
    使用try-catch代码块:
    try{
    //可能产生异常的代码块
    }catch(异常类型 e){
    //对异常进行出来的代码块
    }
    实例:
public class ExceptionDemo1 {
    
    

	/**
	 * @param args
	 */
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		try {
    
    
			Scanner  input= new Scanner(System.in);
			System.out.println("请输入一个除数:");
			int num1=input.nextInt();
			System.out.println("请输入除数:");
			int num2=input.nextInt();
			System.out.println(String.format("%d/%d=%d", num1, num2,num1/num2));
			System.out.println("感谢使用本程序!");
		} catch (Exception e) {
    
    
			// TODO: handle exception
			System.err.println("出现错误!被除数和除数必须为整数,并且除数不能为0");
			e.printStackTrace();
		}
	}

}

使用try-catch-finally处理异常:

public class ExceptionDemo2 {
    
    
	public static void main(String[] args) {
    
    
		Scanner input = new Scanner(System.in);
		try {
    
    
			System.out.println("请输入被除数:");
			int num1 = input.nextInt();
			System.out.println("请输入除数:");
			int  num2 = input.nextInt();
			System.out.println(String.format("%d/%d=%d", num1,num2,num1/num2));
		} catch (Exception e) {
    
    
			System.err.println("出现错误:除数和被除数必须是整数,并且除数不能为0");
			System.out.println(e.getMessage());
		}finally{
    
    
			System.out.println("谢谢使用本程序");
		}
	}
}

Try-catch-finally结构中try语句块必须存在,catch、finally语句块为可选,但是两者必须出现其中一个
执行流程:

  1. try中的所有语句正常执行完毕,finally语句就会执行。
  2. try中发生异常,无论catch能否捕捉到异常,finally中的语句都将被执行
    ※注意:
    即使try语句、catch语句块中存在return语句,finally语句块中的语句也会执行,当发生异常时的语句执行顺序是:执行try和catch语句块中return之前的语句→finally语句→再执行try或catch中的return语句

异常体系结构

在这里插入图片描述
java.lang.Throwable
|-----java.lang.Error:一般不编写针对性的代码进行处理。
|-----java.lang.Exception:可以进行异常的处理
|------编译时异常(checked)
|-----IOException
|-----FileNotFoundException
|-----ClassNotFoundException
|------运行时异常(unchecked,RuntimeException)
|-----NullPointerException
|-----ArrayIndexOutOfBoundsException
|-----ClassCastException
|-----NumberFormatException
|-----InputMismatchException
|-----ArithmeticException
Throwable: 有两个重要的子类:**Exception(异常)**和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。

Exception(异常):是程序本身可以处理的异常。根据处理方式Exception又分为运行时异常和编译时异常

运行时异常:

  1. 是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序 员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子 类都是运行时异常。
  2. 对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对 程序的可读性和运行效率产生影响。
    编译时异常:
    1, 是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一 般性异常。编译器要求Java程序必须捕获或声明所有编译时异常。
    2.对于这类异常,如果程序不处理,可能会带来意想不到的结果.

异常处理方式

  1. try-catch-finally:如上例
  2. throws + 异常类型
    实例:
package com.qwy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ExceptionTest2 {
    
    
	
	
	public static void main(String[] args){
    
    

		try {
    
    
			method1();
		} catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//抛出异常
	public static void method1() throws FileNotFoundException,IOException{
    
    
		File file = new File("hello1.txt");
		FileInputStream fis = new FileInputStream(file);
		
		int data = fis.read();
		while(data != -1){
    
    
			System.out.print((char)data);
			data = fis.read();
		}
		
		fis.close();
		
		System.out.println("hahaha!");
	}
	
	
}


关于手动抛出异常和自定义异常后期补充

猜你喜欢

转载自blog.csdn.net/qwy715229258163/article/details/114746566