JAVA快速入门-异常
Tips:
异常:程序在运行过程中发生由于外部问题(如硬件错误、输入错误)等导致的程序异常事件。(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象。异常(Exception)都是运行时的。编译时产生的不是异常,而是错误(Error)。需要注意的是,程序设计导致的错误(Error)不属于异常(Exception)。JAVA中异常都是从类Throwable类派生出来的,而Throwable类是直接从Object类继承而来,可见Java对异常处理的重视程度。
Error:系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理;
Exception:可以处理的异常
RuntimeException:可以捕获,也可以不捕获的异常。
IOException:必须被捕获的异常。
它们的具体分类如下图:
下面以一个可能出现异常的代码作为例子,然后开始对这个异常做处理和完善。
/* 下面程序的运行方式
* java Div 6 2
* 6/2=3
*/
public class Div{
public static void main(String args[]){
int m = Integer.parseInt(args[0]);//从字符串里面解析出整数
int n = Integer.parseInt(args[1]);
int r = div(m, n);
System.out.println(m+"/"+n+"="+r);
}
public static int div(int m, int n){
int r = m / n;
return r;
}
}
上面一个简单的程序例子,正常按要求输入时是不会有异常的,但是如果输入例如” java Div 6 0 “,那么它就会产生算数异常,如下:
这里的“ArithmeticException”就是算数异常,属于 RuntimeException 这个运行异常(这个异常可以处理可以不处理,不处理程序会退出,但是编译是能够通过的),在进行处理时可以在本方法内自己进行处理,也可以抛出让调用者去处理,下面代码是本方法内进行处理的方式:
public static int div(int m, int n){
int r=0;
/* try catch进行处理后程序在发生异常时就不会奔溃 */
try {
r = m / n;
} catch (ArithmeticException e) {//捕获算数异常
System.out.println(e);
} finally {//加了 finally 无论是否发生异常都会执行这段代码
System.out.println("this is finally of div");
}
/* 算数异常属于runtime异常可以处理也可以不处理,不处理就奔溃,但编译能通过 */
return r;
}
上面的程序在自己方法内进行处理,如果想让调用者处理,可以抛出这个异常,如下:
public class Div4{
public static void main(String args[]){
int m = Integer.parseInt(args[0]);//从字符串里面解析出整数
int n = Integer.parseInt(args[1]);
int r = 0;
/* 对异常进行处理 */
try {
r = div(m, n);
} catch (ArithmeticException e){
System.out.println(e);
}
System.out.println(m+"/"+n+"="+r);
}
/* 这里用 throws 把算数异常抛出给调用者*/
public static int div(int m, int n)throws ArithmeticException{
int r=0;
r = m / n;
return r;
}
}
如果这个异常想要本方法内处理一部分,也想让调用者也做处理的话,代码可以这样写:
public class Div6{
public static void main(String args[]){
int m = Integer.parseInt(args[0]);//从字符串里面解析出整数
int n = Integer.parseInt(args[1]);
int r = 0;
try {
r = div(m, n);
} catch (ArithmeticException e){
System.out.println("main :"+e);
}
System.out.println(m+"/"+n+"="+r);
}
/* 把异常丢给调用者处理,main里面如果不做处理也会奔溃 */
public static int div(int m, int n)throws ArithmeticException{
int r=0;
try {
r = m / n;
} catch (ArithmeticException e){
System.out.println("div :"+e);
/* 这里要丢出异常main才会处理,否则调用者mian是捕捉不到这个异常的 */
throw e;
}
return r;
}
}
需要说明的是,对于“不可查的异常”, runtime 异常属于这个范畴,系统会自动抛出它,所以 div 方法后面的 throws 我们也可以不写。下面写一个同时捕获多个异常的程序,如下:
public class Div8{
public static void main(String args[]){
int m = 0;
int n = 0;
int r = 0;
try {
m = Integer.parseInt(args[0]);
n = Integer.parseInt(args[1]);
r = div(m, n);
/* 当异常太多,每个都写太麻烦,可以捕获它们的父类 */
} catch (ArithmeticException e){//算数异常
System.out.println("main :"+e);
} catch (NumberFormatException e){//数据格式异常
System.out.println("main :"+e);
} catch (RuntimeException e){//它们的父类,属于这个异常的子类都会被处理
System.out.println("main :"+e);
}
System.out.println(m+"/"+n+"="+r);
}
/* 对于“不可查异常”, 系统也会抛出它,写不写后面这个throws效果一样 */
public static int div(int m, int n)throws ArithmeticException{
int r=0;
try {
r = m / n;
} catch (ArithmeticException e){
System.out.println("div :"+e);
/* 这里执行throw之前会先去执行finally,但是如果finally它return了,
这里就不会执行throw,会导致异常没有抛出 */
throw e;
} finally {
System.out.println("finally of div");
/* 这里不能 return */
//return r;
}
return r;
}
}
上面是属于runtime运行异常,可处理也可不处理,属于不可查异常范畴,下面是写一个可查的异常,即我们必须处理的异常,否则连编译都编译不过,程序如下:
public class Div9{
public static void main(String args[]){
int m = 0;
int n = 0;
int r = 0;
try {
m = Integer.parseInt(args[0]);
n = Integer.parseInt(args[1]);
r = div(m, n);
} catch (ArithmeticException e){
System.out.println("main :"+e);
} catch (NumberFormatException e){//数据格式异常
System.out.println("main :"+e);
} catch (RuntimeException e){//它们的父类
System.out.println("main :"+e);
} catch (Exception e){//捕获自己手工创建的可见异常,必须捕获并处理
System.out.println("main :"+e);
}
System.out.println(m+"/"+n+"="+r);
}
/* 这里是“可查的异常”,所以如果div没有处理的话 throws 就必须写 */
public static int div(int m, int n)throws Exception{
int r=0;
try {
r = m / n;
} catch (ArithmeticException e){
System.out.println("div :"+e);
/* 手工创建的可见异常,扔出去让别人处理 */
throw new Exception("My Error");
} finally {
System.out.println("finally of div");
}
return r;
}
}
上面创建了可查的异常后,抛出来让调用者 main 来处理了,如果想自己处理了,就可以不用加 throws,如下:
public static int div(int m, int n){
int r=0;
try {
r = m / n;
} catch (ArithmeticException e){
System.out.println("div :"+e);
try {
throw new Exception("My Error");
} catch (Exception e2){ //不抛出异常就得处理
System.out.println("div :"+e2);
}
} finally {
System.out.println("finally of div");
}
return r;
}
最后以思维导图做一个总结:
上一篇: 精讲C++
下一篇: Zookeeper知识点