异常是导致程序中断执行的一种指令流。在出现错误之后程序将不会按照既定的方式执行,而是中断执行。为了保证程序出现的非致命错误之后程序依然可以正常完成,所以需要有一个完善的异常处理机制,保证程序的正常运行。
public class Demo01 {
public static void main(String[] args) {
System.out.println("程序开始");
System.out.println(10 / 0);
System.out.println("程序结束");
}
}
程序开始
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Demo01.main(Demo01.java:4)
异常处理结构
try{
//业务实现代码(可能发生异常)
}
[catch(异常类1 异常现象){
//异常类1的处理代码
}
catch(异常类2 异常现象){
//异常类2的处理代码
}
……
catch(异常类n 异常现象){
//异常类n的处理代码
}]
[finally{
//不管是否出现异常都要执行的代码
}]
示例
public class Demo01 {
public static void main(String[] args) {
System.out.println("程序开始");
try {
System.out.println(10 / 0);
} catch (ArithmeticException e) {
// 处理异常
// 直接输出一个异常类的对象
System.out.println(e);
// 获取完整异常信息,使用异常类的printStackTrace()方法。
e.printStackTrace();
} finally {
System.out.println("一定会执行的语句代码");
}
System.out.println("程序结束");
}
}
程序开始
java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at Demo01.main(Demo01.java:5)
一定会执行的语句代码
程序结束
1、只有才程序运行过程中才会产生异常,一旦程序运行过程过产生异常,将自动进行指定类型的异常类实例化处理。
2、如果程序没有提供异常处理的支持,则采用JVM
默认异常处理方式,首先进行异常信息的打印,然后直接退出当前程序。
3、如果程序提供了异常处理的支持,则产生的异常类对象会被try语句捕获;
4、try捕获到异常之后会与其匹配的catch中的异常类型进行依次比对;如果此时与catch的捕获异常类型相同,则认为应该使用此catch进行异常处理,如果不匹配此继续匹配后续的catch类型,如果没有任何的catch匹配成功,那么表示该异常无法进行异常处理。
5、不管异常是否处理最终都要执行finally语句,但是执行完finally
语句之后会进一步当前判断异常是否处理,如果处理过了,则继续向后执行其他代码,如果交由JVM
进行默认的异常处理。
如果进行多个异常处理操作,捕获范围大的一定放到捕获范围小的之后。
在执行程序的过程中有可能会产生异常,如果定义了一个方法,就应该明确的告诉使用者这个方法会产生何种异常。那么就可以在方法上使用throws关键字进行异常类型的标注,如果产生异常调用处处理。
class MyMath {
// 这个代码执行的时候可能会产生异常,如果产生异常,调用处处理
public static int div(int x, int y) throws Exception {
return x / y;
}
}
public class Demo02 {
// 在主方法上继续抛出异常
public static void main(String[] args) {
try {
System.out.println(MyMath.div(10, 0));
} catch (Exception e) {
e.printStackTrace();
}
}
}
此关键字的主要作用在于表示手工进行异常的抛出,即:手工产生一个异常类的实例化对象,并且进行异常的抛出处理。
public class Demo03 {
public static void main(String[] args) {
try {
// 异常对象不再由系统生成,而是由手工定义的
throw new Exception("自己抛着玩的对象");
}catch (Exception e){
e.printStackTrace();
}
}
}
java.lang.Exception: 自己抛着玩的对象
at Demo03.main(Demo03.java:5)
throw:在代码块中使用,主要是手工进行异常对象的抛出。
throws:是在方法定义上使用的,表示将此方法中可能产生的异常明确告诉给调用处并由调用处进行处理。
class MyMath02 {
// 异常交给调用处处理,使用throws
public static int div(int x, int y) throws Exception {
int temp = 0;
System.out.println("开始");
try {
temp = x / y;
} catch (Exception e) {
// 向上抛异常对象
throw e;
} finally {
System.out.println("结束");
}
return temp;
}
}
public class Demo04 {
public static void main(String[] args) {
try {
System.out.println(MyMath02.div(10, 0));
} catch (Exception e) {
e.printStackTrace();
}
}
}
开始
结束
java.lang.ArithmeticException: / by zero
at MyMath02.div(Demo04.java:7)
at Demo04.main(Demo04.java:21)
RuntimeException
RuntimeException
是Java提供的一个灵活的可选的异常处理的父类,这个类的子类可以不需要强制性处理。
1、RuntimeException
与Exception
的区别?
RuntimeException
是Exception的子类
RuntimeException
标注的异常可以不进行强制性处理,而Exception异常必须强制性处理!!
2、常见的RuntimeException
:
NumberFromatException
ClassCastException
NullPointerException
JDK提供的异常类不能满足自己的开发需求时需要考虑自定义异常类。
第一种:继承Exception
第二种:继承RuntimeException
class BombException extends RuntimeException{
public BombException(String msg){
super(msg);
}
}
class Food{
public static void eat(int num) throws BombException {
if (num > 10){
throw new BombException("吃太多了,肚子爆了");
}else {
System.out.println("正常开始吃,不怕吃胖");
}
}
}
public class Demo6 {
public static void main(String[] args) throws Exception{
Food.eat(11);
}
}
assert关键字的作用是确定代码执行到某行之后一定是所期待的结果。并不一定是准确的,也有可能出现偏差,但是这种偏差不应该影响程序的正常运行。
public class Demo7 {
public static void main(String[] args) throws Exception{
int x = 10;
// 中间会经过许多的x变量的操作步骤
assert x == 100 : "x的内容不是100";
System.out.println(x);
}
}
10
断言并不是程序必须执行的步骤,需要特点环境下才可以运行的步骤。