异常

异常是导致程序中断执行的一种指令流;

异常发生时系统会自动产生异常类的实例化对象,try语句捕获的就是这个异常类的实例化对象;

1.程序异常处理机制:

1.try{…}catch(…){…}

public class Demo{
	public static void main(String[] args){
		System.out.println("********程序开始执行*********");
		try{
			System.out.println("********开始计算:" + (10/0) + "*********");
		}catch(ArithmeticException e){
			System.out.println("已经捕获到异常:" + e);
		}
		System.out.println("********程序执行结束*********");
	}
}
输出结果:
********程序开始执行*********
已经捕获到异常:java.lang.ArithmeticException: / by zero
********程序执行结束*********

可以调用"printStackTrace()"输出异常详细信息

将上例中catch语句改为:

...
catch(ArithmeticException e){
			e.printStackTrace();
		}
...
输出结果:
********程序开始执行*********
java.lang.ArithmeticException: / by zero
        at Demo.main(Demo.java:5)
********程序执行结束*********

2.try{…}catch(…){…}finally{…}

finally{}代表异常处理的出口,不管有没有异常出现,finally{}语句都会执行

public class Demo{
	public static void main(String[] args){
		System.out.println("********程序开始执行*********");
		try{
			System.out.println("********开始计算:" + (10/0) + "*********");
		}catch(ArithmeticException e){
			e.printStackTrace();
		}finally{                                //finally{}语句
			System.out.println("我会执行!");
		}
		System.out.println("********程序执行结束*********");
	}
}
输出结果:
********程序开始执行*********
java.lang.ArithmeticException: / by zero
        at Demo.main(Demo.java:5)
我会执行!
********程序执行结束*********

3.处理多个异常:try{…}catch(…){…}catch(…){…}catch(…){…}. . .finally{…}

可以有任意多个catch!

2.Error和Exception

java.lang.Object下有Throwable子类,该子类是可以处理异常的最大类型;

Throwable子类下有Error类和Exception类;

Error:程序还未执行出现的错误,开发者无法处理;

Exception:程序运行过程中出现的错误,开发者可以处理,是真正在开发中需要关注的;

所有发生的异常都可以用Exception来处理,即:

...
catch(Exception e){
			e.printStackTrace();
		}
...

这包含了所有异常,如果使用Exception,要将它放在最后一个catch语句中,否则后面会出错“异常已捕获”;

使用Exception会使错误不明确!要具体情况具体分析处理!

3.throws关键字

程序运行过程中可能出现异常,开发者需要在程序中标注该程序可能出现何种异常,这时就可以使用throws关键字;

throws用法:

注意:用throws关键字,在主方法调用时要加上try{…}catch(…){…}进行强制处理,否则会报错!但是!Java考虑到代码编写的方便,提供了一个灵活可选的异常父类"RuntimeException",这个类的子类不用强制处理

class JS{
	public static int getInfo(int x,int y) throws Exception{
		return x/y;
	}
}
public class Demo{
	public static void main(String[] args){
		try{
			System.out.println(JS.getInfo(10,2));
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

主方法也可以抛出异常,这样无需加try{…}catch(…){…}语句捕获异常,系统自动处理;

//实例:
public class Demo{
	public static void main(String[] args) throws Exception{
		System.out.println(10/0);
	}
}

4.throw关键字

此关键字主要作用为表示手工进行异常抛出,即:此时将手工产生异常的实例化对象,并进行实例化处理;

throw关键字通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行。通过throw抛出异常后,如果想在上一级代码中来捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法声明中指明要跑出的异常;如果要捕捉throw抛出的异常,则必须使用try—catch语句。

throw用法:
public class Demo{
	public static void main(String[] args){
		try{
			throw new Exception("自定义异常!");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
输出结果:
java.lang.Exception: 自定义异常!
        at Demo.main(Demo.java:4)

5.自定义异常类

可以自定义异常类,以在特定时刻抛出特殊异常。

两种实现方案:继承Exception(必须强制处理)或者继承RuntimeException(无需强制处理);

class BoomException extends Exception{     //继承Exception类
	public BoomException (String str) {
		super(str);
	}
}
class Eat{
	private int raceNum = 0;
	public Eat(int r) {
		this.raceNum = r;
	}
	public void eating() throws BoomException{
		if(this.raceNum > 10){
			throw new BoomException("吃太撑了!");     //手动抛出异常
		}
		else {
			System.out.println("正在吃饭!");
		}
	}
}

public class Demo{
	public static void main(String[] args){
		Eat e = new Eat(11);
		try{
			e.eating();
		}catch(Exception x){
			x.printStackTrace();
		}
	}
}

6.assert断言

不是Java强制执行的,需要在运行程序时加上"-ea"参数才会执行断言语句;

如果在特定位置没有得到期望的结果,就抛出异常终止程序运行;

public class Demo{
	public static void main(String[] args){
		int a = 10;
		assert a == 100 : "a的值不是100";
		System.out.println(a);
	}
}

命令提示符执行语句:

javac Demo.java
java -ea Demo
输出结果:
Exception in thread "main" java.lang.AssertionError: a的值不是100
        at Demo.main(Demo.java:4)