Java异常处理

一、简述

异常:就是程序在运行时出现不正常情况。

异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。其实就是java对不正常情况进行描述后的对象体现。

对于问题的划分:

  • 严重的问题。
  • 非严重的问题。

对于严重的,java通过Error类进行描述。对于Error一般不编写针对性前的代码对其进行处理。(已经没救了,何必管呢?)

对于非严重的,java通过Exception类进行描述。对于Exception可以使用针对性的处理方式进行处理。

无论Error或Exception都具有一些共性内容。如:不正常情况的信息,引发原因等。

Throwable
	|--Error
	|--Exception

二、异常的处理

java提供了特有的语句进行处理。

try
{
	//需要被检测的代码;
}
catch(异常类 变量)
{
	//处理异常的代码(处理方式)
}
finally
{
	//一定会执行的语句
}

了解C++的都知道在C++的异常处理中并没有finally块,那么Java中为什么要有这个呢?

只因为Java的对象中没有析构函数,在C++中,即使异常抛出了,最终也会执行到析构函数。所以Java将析构函数的功能用finally来表示,就像析构函数一样,这个块无论是否抛出异常,也必将会执行到。

所以对于对象的销毁,资源的关闭等等原本写在析构函数中的东西,在Java中,我们可以将它写到finally中。


三、对捕获的异常对象进行处理

class Demo
{
	int div(int a, int b) throws ArithmeticException
	{
		if(b < 0)
			throw new ArithmeticException();  //手动通过throw关键字抛出一个自定义的异常对象
			
		return a / b;
	}
}

public class ExceptionDemo {
	public static void main(String[] args) {
		Demo d = new Demo();
		try 
		{
			int ret = d.div(4, 0);
			System.out.println(ret);
		}
		catch(ArithmeticException e)
		{
			System.out.println("除数为0错误");
			System.out.println(e.getMessage());  //by zero
			System.out.println(e.toString());    //异常名称: 异常值

			e.printStackTrace();  //异常名称,异常信息,异常出现的位置
			                      //jvm默认的异常处理机制,便是在调用printStackTrace方法.
								  //打印异常的堆栈跟踪信息.
		}
	}
}

四、throw和throws的区别

  • throws使用在函数上,表示该函数可能会发生异常。 throws后面跟的异常类,可以跟多个,用逗号隔开。
  • throw使用在函数内,用于抛出异常的信息。
    throw后跟的是异常对象。

五、多异常处理

声明异常时,建议声明更加具体的异常,这样处理可以更具体的处理。

要抛出多个异常时,throws后面用逗号分隔异常名称,要有分别处理这些异常的catch块。

在进行catch中,一定要定义具体的处理方式,不要简单的定义一句e.printStackTrace(),亦不要仅书写一条输出语句。

可以将此些异常记录日志,生成异常日志文档。


六、自定义异常

因为项目中会出现特有的一些问题,而这些问题并未被Java所描述并封装对象,所以对于这些特有的问题可以按照Java对问题封装的思想,将特有的问题,进行自定义的异常封装。

当在函数内部出现了throw抛出异常对象,那么就必须给出对应的错误处理动作。

要么在内部try catch处理,要么在函数上声明让调用者处理。

一般情况下,函数内出现异常,函数上需要声明。

如何定义异常信息?
因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息通过super语句传递给父类。然后就可通过getMessage()输出信息。

自定义异常必须是自定义类继承Exception。

继承Exception的原因:
异常体系有一个特点,因为异常类和异常对象都被抛出。
他们都具备可抛性,这个可抛性是Throwable这个体系中的独有特点。
只有这个体系中的类和对象,才可被throw和throws操作。


七、RuntimeException

对于异常,分两种:

  • 编译时被检测的异常。
  • 编译时不被检测的异常,运行时异常,RuntimeException及其子类。

RuntimeException是Exception中的一个特殊的子类异常,称为运行时异常。

如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。

如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。

之所以不用在函数上声明,是因为不需要让调用者处理。当该异常发生时,期望程序停止。因为在运行时,出现了无法继续运算的情况,期望停止程序后,对代码进行修正。

自定义异常时,如果该异常发生后,导致无法继续进行运算,就让自定义异常继承RuntimeException。

class Demo 
{
	int div(int a, int b)
	{
		if(b == 0)
			throw new ArithmeticException();  //手动通过throw关键字抛出一个自定义的异常对象
		if(b < 0)
			throw new FuShuException("除数为负数", b);  //运行期异常,无需声明throws也可编译通过
		
		return a / b;
	}
}

public class ExceptionDemo {
	public static void main(String[] args) {
		Demo d = new Demo();
		try {
			int ret = d.div(4, -1);
			System.out.println("ret=" + ret);
		}catch(ArithmeticException e) {
			System.out.println(e.getMessage());
		}
	}
}
posted @ 2018-07-19 14:49  cpluspluser  阅读(217)  评论(0编辑  收藏  举报