Java:异常的处理(加深理解)

目录

1.关于异常 

异常的分类

2.异常处理

try -catch-finally的使用

throw和throws关键字

 自定义异常:


1.关于异常 

        什么是异常:

        - 异常字面意思就是‘意外’,‘例外’的意思,也就是非正常的意思。

        - 异常本质上是程序上的错误。

        为什么要处理异常:

        如果异常不处理的话,程序就会强行终止,不会继续运行下去。假若程序在运行期间出现

了错误,如果置之不理,程序便会终止或直接导致系统崩溃,显然这不是我们希望看到的结果。

        程序中的异常

        -错误在我们编程的过程中会经常发生的,包括编译期间和运行期间的错误

        - 在编译期间出现的错误有编译器帮我们一起修正,然而运行期间的错误便不是编译器力

          所能及的了,并且运行期间的错误往往是难以入料的。

        - 事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误。比如使用空的引

 用、数组下标越界、内存溢出错误等,这些都是意外的情况。

        例如:(运行期间的错误,即编译器不能识别的)

                空指针异常NullPointerException):

public class Demo12 {

	public static void main(String[] args) {
        //创建一个空数组
		String str = null;
        //输出数组的长度
		System.out.println(str.length());
	}
}

                数组访问时下标越界ArrayIndexOutOfBoundsException):

public class Demo12 {

	public static void main(String[] args) {
		int[] sry = {1, 2, 3};
		for (int i = 0; i <=3; i++) {
			System.out.println(sry[i]);
		}
	}
}

        上述程序中,定义了一个长度为3的整型数组,在遍历的过程中有出现了sry[3],但是数组并没有这个元素。

                算数运算时除数为0ArithmeticException):

public class Demo12 {

	public static void main(String[] args) {
		int one = 12;
		int two = 0;
		System.out.println(one/two);
		
	}
}

        当除数为0时,编译器并不能发现错误,只在运行的时候会报错。

                类型转换时无法正常转型ClassCastException):

class Animal{
	
}

class Dog extends Animal{
	
}

class Cat extends Animal{
	
}

public class Demo12 {

	public static void main(String[] args) {
		Animal a1 = new Dog();
		Animal a2 = new Cat();
		Dog d1 = (Dog)a1;
		Dog d2 = (Dog)a2;
	}
}

         上述程序中,a2是Cat类的实例,与Dog类无关。

异常的分类

        在Java中,通过Throwable及其子类描述各种不同的异常类型(Throwable类是所有异常的父类)。

        Throwable有两个重要的子类:Exception和Error注意:Error异常一般处理不了(次异常与硬件有关)。我们一般处理的都是Exception。

          unchecked exception(非检查异常),也称运行时异常(RuntimeException),比如常见的NullPointerException、IndexOutOfBoundsException。对于运行时异常,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。

        checked exception(检查异常),也称非运行时异常(运行时异常以外的异常就是非运行时异常),java编译器强制程序员必须进行捕获处理,比如常见的IOExeption和SQLException。对于非运行时异常如果不进行捕获或者抛出声明处理,编译都不会通过。

      1) Error

        Error是程序无法处理的错误,表示运行应用程序中比较严重的问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM虚拟机出现了问题。

        这些错误是不可查的,因此我们在编写的过程中不需要关心这类的异常

        2)Exception

        Exception是程序本身可以处理的异常。Exception异常通常包括checked exception 和 unchecked exception。

2.异常处理

        ·Java中应用程序中,异常处理机制为:抛出异常、捕捉异常。

  • 抛出异常:
    • 当一个方法出现错误引发异常时,方法创建异常对象并交付运行时的系统
    • 异常对象中包含了异常类型和异常出现时的程序状态等异常信息。
    • 运行时系统负责寻找处置异常的代码并执行
  • 捕获异常
    • 在方法抛出异常之后,运行时系统间转换为寻找合适的异常处理器。
    • 运行时系统从异常的方法开始,依次回查调用栈中的方法当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。
    • 当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止
    • 对于运行时异常,Java技术所要求的异常处理方式有所不同
    • 总体来说,Java规定:对于可查异常必须捕捉、或声明抛出。允许忽略不可查的RuntimeException和Error
    • 总的来说,异常总是先被抛出,后被捕获的。  

        异常时通过5个关键字来实现的:try、catch、finaly、throw、throws.

 

try -catch-finally的使用

代码格式如下:

public void method(){
        try{

                //代码段1

                //产生异常的代码段2
        }catch(异常类型 ex){

                //对异常进行处理的代码段3
        }finally{

                //代码段4
        }

}

        //注意try块后面必须跟0个或多个catch块,或者直接跟finally块。

        被try包围的代码说明这一段代码可能会发生异常,一旦发生异常,异常就会被catch捕捉到,然后需要在catch块中进行异常的处理。

public class Demo12 {

	public static void main(String[] args) {
		System.out.println(123);
		try {
			int sum = 12/0;
			System.out.println(sum);
		}catch(ArithmeticException e) {
			System.out.println("除数不能为0");
            //打印异常的堆栈信息,并不会影响程序的运行
           // e.printStackTrace();
		}finally {
			System.out.println(456);
		}
		System.out.println(789);
	}
}

        上述代码中,显而易见int sum = 12/0;肯定会报错的,当运行到这句话的时候,异常就会被catch捕获到,而后就会运行catch块中的语句对异常进行处理。处理过后并不会影响之后的程序运行。若不处理JVM虚拟机就会崩溃,从而程序强行终止。finally语句,除非是遇到Error异常或者JVM虚拟机被强行停止(System.exit(0)),否则finally块中的语句都会被执行(return也不会影响finally块的执行)。

输出结果:

  • 实际应用中的经验与总结
    • 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
    • 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗落的异常
    • 对于不确定的代码,也可以加上try-catch,处理潜在的异常
    • 尽量去处理异常,切记只是简单的调用printStackTrace()去打印输出
    • 具体如何处理异常,要根据不同的业务需求和异常类型去决定
    • 尽量添加finally语句去释放占用资源
import java.util.InputMismatchException;
import java.util.Scanner;

public class TryDemo4 {

	public static void main(String[] args) {
		testOne();
    }
	
    public static void testOne(){
 		try {
 			Scanner sc = new Scanner(System.in);
 			System.out.println("请输入第一个数字:");
 			int a = sc.nextInt();
 			System.out.println("请输入第二个数字:");
 			int b = sc.nextInt();
 			int result = a / b;
 			System.out.println("result:" + result);
 		}catch(ArithmeticException e) {
 			System.out.println("请不要将除数至为0");
 		}catch (InputMismatchException e) {	
 			System.out.println("只能输入数字");
 		}catch (Exception e) {
 			e.printStackTrace();
 		}finally {
			System.out.println("===程序结束===");
		}
 		System.out.println(123);
	}
}

运行结果1(当b为0时)

 运行结果2(正常输入):

 运行结果3(当输入字母时):

throw和throws关键字

        在Java中还提供了另一种异常处理方式即抛出异常,顾名思义,也就是一旦发生异常,我们就把这个异常抛出去,让调用者去进行处理,自己不进行具体处理,此时需要用到throw和throws关键字。

        throws语句在格式

public void method() throws 异常1,异常2,异常3,...,异常N{

        可能产生异常的代码
}

        代码如下:

import java.util.InputMismatchException;
import java.util.Scanner;

public class TryDemo5 {

	public static void main(String[] args) {
		try {
			testOne();
		} catch(ArithmeticException e) {
 			System.out.println("请不要将除数至为0");
 		}catch (InputMismatchException e) {	
 			System.out.println("只能输入数字");
 		}catch (Exception e) {
 			e.printStackTrace();
		}
		System.out.println(123);
	}


	/**
	 * 如果抛出的是非检查异常(运行时异常RuntimeException),可以用文档注释标注异常信息
	 * @return  double result
	 * @throws InputMismatchException
	 * @throws ArithmeticException
	 */
	public static double testOne() throws InputMismatchException, ArithmeticException,Exception{
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入第一个数字:");
		int a = sc.nextInt();
		System.out.println("请输入第二个数字:");
		int b = sc.nextInt();
		return a / b;
	}
}

        当然还可以使用throw关键字来手动抛出异常。例如:
创建一个hotelRule类,只允许18岁以上或者80岁以下的人来住。代码如下:

public class Demo12 {

	public static void main(String[] args) {
		try {
			hotelRule();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	public static void hotelRule() throws Exception {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入客户年龄:");
		int age = sc.nextInt();
		if(age < 18 || age > 80) {
			throw new HotelException();
		}else {
			System.out.println("入住成功");
		}
	}
}

        e.getMessage()方法获取的时Exception类构造方法的参数。

自定义一个异常类,并且调用父类的构造方法

public class HotelException extends Exception{
	
	public HotelException() {
		super("由于你年龄问题,无法入住");
	}
}

1)对代码块用try..catch进行异常捕获处理;

2)在 该代码的方法体外用throws进行抛出声明,告知此方法的调用者这段代码可能会出现这些

      异常,你需要谨慎处理。此时有两种情况:

        如果声明抛出的异常是非运行时异常,此方法的调用者必须显示地用try..catch块进行捕获

        或者继续向上层抛出异常。

        如果声明抛出的异常是运行时异常,此方法的调用者可以选择地进行异常捕获处理。

3)在代码块用throw手动抛出一个异常对象,此时也有两种情况,跟2)中的类似:

  如果抛出的异常对象是非运行时异常,此方法的调用者必须显示地用try..catch块进行捕获或

        者继续向上层抛出异常。

  如果抛出的异常对象是运行时异常,此方法的调用者可以选择地进行异常捕获处理。

  (如果最终将异常抛给main方法,则相当于交给jvm自动处理,此时jvm会简单地打印异常信息)

代码执行:

 自定义异常:


        使用Java内置的异常类可以描述在编程时主线的大部分异常情况

        也可以通过自定义异常描述待定业务产生的异常类型;

        所谓自定义异常就是定义一个类,去继承Exception类或者它的子类

在继承当中使用异常的一些情况

  • 父类的函数如果没有声明任何异常,那么子类重写的函数也不能声明
  • 就算子类当中出现了编译时异常也只能进行捕获不能声明
  • 子类的函数如果声明了编译时异常,那么子类重写的函数只能声明父类异常或父类异常的子类

参考资料:Java异常处理和设计 - Matrix海子 - 博客园Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分。一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度。试想一下,如果一个项目从头到尾没有考虑过异常http://www.cnblogs.com/dolphin0520/p/3769804.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值