异常
异常是导致程序中断执行的一种指令流;
异常发生时系统会自动产生异常类的实例化对象,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)