Java基础编程之异常处理

Java异常类是对于程序中可能出现的错误或者异常的一种处理方式。在设计程序的过程中,对于可能出现的异常错误,比如说用户输入错误,设备错误,磁盘满了或者代码错误等等,通常采用异常处理的方式来进行处理可能的错误。 JAVA的异常处理机制:如果某个方法不能按照正常的途径完成任务,就可以通过另一种路径退出该方法,并处理可能出现的错误。在这种情况下会抛出一个封装了错误信息的对象。 这个方法会立刻退出同时不返回任何值。另外,调用这个方法的其他代码也无法继续执行,异常处理机制会将代码执行交给异常处理器。

(一)Java异常

异常:导致程序中断运行的一种指令流。 在理想的情况下,程序完全按照我们设计的流程来执行,但是很多时候会出现这样或者那样的错误,如文件找不到,磁盘满了或者代码错误等,这些错误会影响程序的正常执行,对于这种情况,就有了异常处理情况,即使程序异常了,它也是按照某种逻辑在执行,只是没有按照我们给它安排的逻辑执行。异常在Java中定义为Throwable类,其结构层次图如下:
异常处理层次图

由上图可以看出,Thowable有两个重要的子类,一个是Error类,另一个是Expection类,每一个子类下面还有很多小的分类。

Error类指的是Java运行时系统的内部错误或者资源耗尽错误, 这是程序无法处理的错误,表示运行应用程序中较严重问题,对于这类问题,JVM告知用户,并尽力终止程序。
Expection类指的是 程序本身可以处理的异常。主要分为两类,RuntimeException类异常或者其他异常,由程序错误导致的异常称之为RuntimeExpection,比如说:错误的类型转化,数组访问过界,访问空指针等。而程序本身没有错误,像I/O错误这类问题所导致的异常称之为其他异常,比如说试图打开一个不存在的文件或类。

Java 异常类的另一种分类方式是:可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。

可查的异常(checked exceptions):正确的程序在运行时,出现情理可容的异常,除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。对于此类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
可不查的异常(unchecked exceptions): 包括RuntimeException及其子类和Error。 编译器不要求强制处理的异常。
(二) 异常处理
在 Java 应用程序中,异常处理机制为:抛出异常,捕捉异常

抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,并停止当前执行路径,并将此异常提交给系统。首先像创建普通的java对象一样,使用new在堆上创建一个异常对象;然后,当前的执行路径被终止,并且从当前环境中弹出对异常对象的引用。此时,异常处理机制接管程序,并开始寻找一个恰当的地方继续执行程序,这个恰当的地方就是异常处理程序或者异常处理器,它的任务是将程序从错误状态中恢复,以使程序要么换一种方式运行,要么继续运行下去。

捕捉异常:当系统捕捉到该异常后,寻求相应的代码来看处理该异常,在方法的调用栈中查找合适·的异常处理器,从生成异常的方法开始回溯,直到找到相应的异常处理代码,并在控制台上打印异常信息,包括异常的信息的堆栈的内容。

Java异常处理涉及到五个关键字,分别是:try、catch、finally、throw、throws

  • 处理方法1 捕捉异常:try-catch-finally语句
    try -catch-finally语句是常用的异常处理语句,其结构如下:
      try { 
      code1;
    // 可能会发生异常的程序代码 
       } catch (Type1 id1) {   
        code2
         // 捕获并处理try抛出的异常类型Type1 
          } catch (Type2 id2) {
         code3
                      // 捕获并处理try抛出的异常类型Type2  
                      } finally {  
                      code4 
                      // 无论是否发生异常,都将执行的语句块
                        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

其逻辑框图如下:
在这里插入图片描述

  • try: 制定一段代码,即一次性捕获并处理的范围,用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,(1)程序将跳出try语句块中的其余代码,(2)转而执行catch中的处理器代码,异常就被抛出 。
    注:当异常代码执行完成以后,try语句块中尚未执行的语句不会再执行。
    一个try语句必须有至少一个catch或finally语句。
  • catch用于处理不同类型的异常。捕获顺序为:越是底层的类,越放在下面。常见的方法有:
    toString():显示异常的类名和产生的原因。
    geyMessage( ) : 显示异常的原因。
    printstackTrack() :显示异常发生时堆栈的内容。
  • finally:不管异常处理与否,必须要执行的代码块。比如说关闭外界的资源。
  • 当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
    1)在finally语句块中发生了异常。
    2)在前面的代码中用了System.exit()退出程序。
    3)程序所在的线程死亡。
    4)关闭CPU。
    异常执行图示:
    在这里插入图片描述
    代码示例:
public class TestException 
 { 
     public static void main(String args[]) 
     {  int i = 0; 
      String greetings[] = { " Hello world !", " Hello World !! ",    " HELLO WORLD !!!" }; 
       while (i < 4) { 
         try {    // 特别注意循环控制变量i的设计,避免造成无限循环   
          System.out.println(greetings[i++]);   
          } 
          catch (ArrayIndexOutOfBoundsException e) {
              System.out.println("数组下标越界异常");  
               } finally 
               {    
               System.out.println("--------------------------");  
               }
           }
       }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 处理方法2 抛出异常 Throws、Throw 用法
    如果遇到无法处理的情况,Java便会抛出一个异常,即告诉编译器需要返回什么值,以及可能出现哪些错误。

public void test() throws FileNotFoundException {
method();
}
public void method() throws FileNotFoundException {
//一个会抛出异常的方法
method2();
}
//这里 方法后是throws
public void method2() throws FileNotFoundException {
//这里是throw
throw new FileNotFoundException();
}

  • Throw总是出现在函数体中, 表示手动抛出一个异常,抛出异常的时候,直接在 Throw 后面添加异常的实例即可。 用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。
 
public class Test  {
public static void main(String[] args) {
    try {
        throw new TestException20180809("自定义异常:天王盖地虎");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • Throws 声明过的方法表示此方法不处理异常,找到一个合适的异常类,创建这个类的对象,并将对象抛出。
import java.lang.Exception;
public class TestException {
	static void pop() throws NegativeArraySizeException {
		// 定义方法并抛出NegativeArraySizeException异常
		int[] arr = new int[-3]; // 创建数组
	}
public static void main(String[] args) { // 主方法
	try { // try语句处理异常信息
		pop(); // 调用pop()方法
	} catch (NegativeArraySizeException e) {
		System.out.println("pop()方法抛出的异常");// 输出异常信息
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 自定义异常类:在程序中,如果标准异常类并不能够充分的描述问题,则需要自己来定义一个异常类来解决问题,只需继承 Exception 即可。可以通过以下步骤定义异常类(1)创建自定义异常类。(2)在方法中通过throw关键字抛出异常对象。(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。(4)在出现异常方法的调用者中捕获并处理异常。
import java.lang.Exception;
public class TestException {
	static int quotient(int x, int y) throws MyException { // 定义方法抛出异常
		if (y < 0) { // 判断参数是否小于0
			throw new MyException("除数不能是负数"); // 异常信息
		}
		return x/y; // 返回值
	}
	public static void main(String args[]) { // 主方法
		int  a =3;
		int  b =0; 
		try { // try语句包含可能发生异常的语句
			int result = quotient(a, b); // 调用方法quotient()
		} catch (MyException e) { // 处理自定义异常
			System.out.println(e.getMessage()); // 输出异常信息
		} catch (ArithmeticException e) { // 处理ArithmeticException异常
			System.out.println("除数不能为0"); // 输出提示信息
		} catch (Exception e) { // 处理其他异常
			System.out.println("程序发生了其他的异常"); // 输出提示信息
		}
	}
}
class MyException extends Exception {            // **创建自定义异常类**
	String message; // 定义String类型变量
	public MyException(String ErrorMessagr) { // 父类方法
		message = ErrorMessagr;
	} 
	public String getMessage() { // 覆盖getMessage()方法
		return message;
	}
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

(三)Java常见异常
五种常见的运行时异常

ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针)
ArrayStoreException(数据存储异常,操作数组时类型不一致)
IO操作的BufferOverflowException异常

非运行时异常必须得捕获,否则编译不过去,java编译器要求程序员必须对这种异常进行catch,Java认为Checked异常都是可以被处理(修复)的异常,所以Java程序必须显式处理Checked异常。常见的非运行异常有io异常和sql异常。

IOException、FileNotFoundExcetion 和SQLException

(四)当异常遇到return
在一个方法中,无论 Try 块中有没有异常、Return,只要 Finally 块中有 Return,那么函数的返回值都由 Finally 块提供。
Java异常总结:(1)一个图:异常类型图。(2)五个关键字,try, catch finally throws throw
(3)继承关系:先大后小,(4)异常和重写:子类重写异常范围不能超出父类。
实例说明:

public class TestException {
	public TestException() {
	}
boolean testEx() throws Exception {
	boolean ret = true;
	try {
		ret = testEx1();
	} catch (Exception e) {
		System.out.println("testEx, catch exception");
		ret = false;
		throw e;
	} finally {
		System.out.println("testEx, finally; return value=" + ret);
		return ret;
	}
}

boolean testEx1() throws Exception {
	boolean ret = true;
	try {
		ret = testEx2();
		if (!ret) {
			return false;
		}
		System.out.println("testEx1, at the end of try");
		return ret;
	} catch (Exception e) {
		System.out.println("testEx1, catch exception");
		ret = false;
		throw e;
	} finally {
		System.out.println("testEx1, finally; return value=" + ret);
		return ret;
	}
}

boolean testEx2() throws Exception {
	boolean ret = true;
	try {
		int b = 12;
		int c;
		for (int i = 2; i &gt;= -2; i--) {
			c = b / i;
			System.out.println("i=" + i);
		}
		return true;
	} catch (Exception e) {
		System.out.println("testEx2, catch exception");
		ret = false;
		throw e;
	} finally {
		System.out.println("testEx2, finally; return value=" + ret);
		return ret;
	}
}

public static void main(String[] args) {
	TestException testException1 = new TestException();
	try {
		testException1.testEx();
	} catch (Exception e) {
		e.printStackTrace();
	}
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

运行结果:

i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, finally; return value=false
testEx, finally; return value=false

常见的异常·:
在这里插入图片描述
在这里插入图片描述
JAVA异常知识结构
在这里插入图片描述

posted @ 2020-09-18 21:56  尚拙  阅读(284)  评论(0编辑  收藏  举报