Java中异常处理机制

关于异常的概述

    所谓异常,是指在程序运行过程中由代码产生的一种错误。其体系结构如下(Exception不单单有IOException和RuntimeException):

Throwable类是Java异常类体系结构中的父类( 根类);

Error类:系统错误类,代表程序运行时Java系统内部错误,这种错误程序员一般不用关心,因为他们通常由硬件或者操作系统所引发的,程序员除了告知用户并关闭程序之外,其他的什么也做不了;

Exception类:异常类,该类的对象表示的错误往往是因为算法考虑不周(例如接下来会提到的一个年龄不能为负数的例子)或者由于编程过程中疏忽大意(例如数组下标越界,空指针访问),未考虑到某些特殊情况(例如利用jdbc技术连接数据库的时候,找不到所对应的数据库)而引起的,需要程序员认真对待并尽可能的加以处理。

IOException类:IO异常,它和它的子类都是表示各种I/O错误;

RuntimeException类:Java程序运行时产生的异常,比如数组下标越界,空指针访问等等。

Exception和Error的区别:其错误的性质在根本上是不同的,Exception表示程序员在设计程序时犯的错误,所以程序员是有责任对其进行消除或者解决的。

为了严格规范程序员的行为避免其犯错,Java的异常被分为两大类:Checked(必须要检查出来的)异常和Runtime(运行时出现的)异常。Error和RuntimeException类及其子类的实例属于Runtime异常,编译器对这类异常不做检查,只有运行之后才可以创建相应的异常对象,进而把出现的问题输出出来。 而一切非Runtime异常(主要是IOException及其子类)都属于Checked异常,编译器在编译程序时要检查程序是否对这类异常做了处理(如用try捕获或者throws抛出)。如果是没有做任何处理,则程序无法通过编译,编译器会强制性要求程序员对其做出相应的处理。


异常处理机制  

    1.异常的捕获与处理

        Java中使用try-catch-finally语句来捕获并处理异常。其中try{ }语句块中的代码是程序在正常情况下要去完成的功能,在执行过程中可能会出现异常的语句。它在执行过程中可能会抛出一种或者几种异常对象,在后边的catch语句中进行处理;  catch语句块声明这个catch语句块能够处理的一种特定类型的异常(在Java7及其之后,每一个catch语句块能处理多个异常,每一个异常类型用“|”隔开即可),其{ }中代表具体的处理方案,一般都是输出一个语句提醒用户哪里出了异常和出了什么异常;  finally{ }中无论try { }语句块是否抛出异常,finally语句块都要执行。

        try-catch-finally 语句的执行过程: 首先执行try语句中的代码,如果出现异常,则不再向下执行,直接跳转到catch语句块,JVM会按从上到下的顺序把实际抛出的异常对象与各catch语句块中所声明的异常类进行匹配,如果是某个catch语句块所声明的异常类的对象,则执行这个catch语句块,并且不再执行其他的catch语句块,之后跳转到finally语句块中执行。 如果try语句中没有出现任何异常,则直接跳过catch语句,直接执行finally语句块中的代码。

package com.ExceptionDemo;

public class exceptionDemo {
	public static void main(String[] args) {
			int a,b;
			a = Integer.parseInt(args[0]);
			b = Integer.parseInt(args[1]);
			System.out.println(a+"/"+b+"="+a/b);
	}
}

        以上代码写完之后是没有任何的错误提示的,但是运行起来之后就会在控制台输出:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0

    at com.ExceptionDemo.exceptionDemo.main(exceptionDemo.java:6)

翻译过来就是:

        这一句话说明以上代码出现了 ArrayIndexOutOfBoundsException异常,这个异常的意思就是:数组下标越界。

      看一下帮助文档就会明白:ArrayIndexOutOfBoundsException异常对象是RuntimeException的子类,而由上文可知RuntimeException类及其子类的实例属于Runtime异常,这种异常编译器是不做检查的,所以说在代码写好之后没有任何的错误提示,只有在程序“跑起来”的时候才会报出来。而这类异常虽然我们没有用try-catch-finally语句块或者throws语句做它的处理,但是不代表没有处理,是编译器替我们处理了这种异常(即Error和RuntimeException)。

        以上代码产生的原因: main方法中的字符串类型的数组为空,args[0]和args[1]是没有值的,所以会报数组下标越界这一异常。

解决的办法:不直接运行,而是打开“Run Configurations”窗口,配置程序运行时的输入参数,在“Arguments”标签页的"Program arguments"栏输入“20 5”,然后单击“Run”按钮运行程序。其结果为:20/5=4;

2.声明抛出异常

        语法格式:在出现异常的代码所对应的方法名后面加上“throws <异常列表>”这样一句代码

        运行机制:自己这个类或者方法中不去处理这个异常,而是交给调用这个方法的类去处理它。即谁调用谁处理。

        throws和throw的区别:

            throw关键字表示手动抛出异常,(前面是利用运行出错或者系统自动捕获异常,但是在某些特定的时候我们需要人工来定义一个异常对象,并且采用手动来抛出异常)

package com.ExceptionDemo;

public class exceptionDemo{
	public static void main(String[] args) throws IllegalArgumentException {
		int age = -100;
		System.out.println("这个人的年龄是: "+age);//代码没有一点错误,但是不符合逻辑,因为年龄不能是负数
		//所以可以用一个if语句判断一下
		if(age < 0){
			throw new IllegalArgumentException();//抛出的异常表明向方法传递了一个不合法或不正确的参数。 
		}
	}
}


由以上例子可以看出:throw是用来抛出异常的。throws是用来标识某方法中可能抛出的异常,也就是说就比如以后别人有一个类继承了你这个类之后要去调用你这个抛出了异常的方法,要是这个方法不用throws声明抛出了什么异常是不可以的。【注意】:即使没有声明过允许抛出RuntimeException或者它的子类异常,方法也总能抛出RuntimeException或者其子类异常,这类异常的抛出是默认的

总结:其实异常其实就是:接下来的代码中有可能出现的或者一定会出现的问题(例:用jdbc连接数据库的时候,可能出现连接不上的情况,如果是连接不上怎么办? 用数组组内元素的时候可能会出现数组下标越界的问题,如果说出现了,应该怎么办?等等一系列可能出现的问题),而异常处理机制就相当于是如果这个问题真的出现了,接下来要怎么做。是自行捕获处理呢,还是不管不问的抛出。而且其异常处理机制体现了Java语言的健壮性,就算是异常抛出或者被try代码块捕获后交给catch处理,也不会影响其他代码的执行。

【注意】1、虽然说Exception类是所有异常类的父类,但是最好不用Exception来对异常件进行处理,因为这样子无法精确反馈给用户一个确定的异常,也就是说不知道具体是哪里出现了问题。

             2、catch代码块中的有参数Exception e,而System.out.println( e ),其实就相当于System.out.println(e.toString( ))

猜你喜欢

转载自blog.csdn.net/my_name_is_zwz/article/details/80264684