异常对程序的影响
异常是指导致程序中断执行的一条指令流。
当程序出现非致命错误时,需要一个完善的异常处理机制,保证程序顺利执行。
处理异常
try{
// 可能出现异常的语句
} [ catch(异常类型 异常对象){
// 异常处理
}... ] [ finally{
// 不管是否有异常,最终都会执行
} ]
处理多个异常
public class Abnormal{
public static void main(String args[]){
System.out.println("【1】******程序开始执行*******");
try{
int x=Integer.parseInt(args[0]);
int y=Integer.parseInt(args[1]);
System.out.println("【2】计算"+ x/y );
}catch(ArithmeticException e){
//直接输出一个异常类对象,如果直接输出此对象(.toString();),如果想要获得非常完整的异常信息可以直接使用异常类提供的printStackTrace()方法
e.printStackTrace();
}finally{
//异常处理后的出口
System.out.println("【F】不管是否出现异常都执行");
}
System.out.println("【3】******程序执行结束*******");
}
}
此时可能出现三个异常:
1.(java Abnormal 10 0)
【已处理】java.lang.ArithmeticException
【F】显示 【3】显示
2.(java Abnormal)
【未处理】java.lang.ArrayIndexOutOfBoundsException
【F】显示, 【3】被中断,没有显示
3.(java Abnormal a b)
【未处理】java.lang.NumberFormatException
【F】显示, 【3】被中断,没有显示
所以,如果没有进行正确异常捕获,程序也会被中断(finally正常执行)。所以需要捕获多个异常:
public class Abnormal{
public static void main(String args[]){
System.out.println("【1】******程序开始执行*******");
try{
int x=Integer.parseInt(args[0]);
int y=Integer.parseInt(args[1]);
System.out.println("【2】计算"+ x/y );
}catch(ArithmeticException e){
//直接输出一个异常类对象,如果直接输出此对象(.toString();),如果想要获得非常完整的异常信息可以直接使用异常类提供的printStackTrace()方法
e.printStackTrace();
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}catch(NumberFormatException e){
e.printStackTrace();
}finally{
//异常处理后的出口
System.out.println("【F】不管是否出现异常都执行");
}
System.out.println("【3】******程序执行结束*******");
}
}
但是如果知道有这些错,加上判断语句不就可以了?为啥要有异常。
异常处理流程
程序之中,可能处理的最大异常类型就是Throwable,他的子类有两个:
- Error:程序开始执行时出现的错误,开发者无法处理。
- Exception:程序中出现的异常。
当处理多个异常时,要把范围大的异常放在范围小的异常之后。
throws关键字
如果定义了某些方法,明确告诉使用者此方法会产生哪种异常。那么就可以在方法的声明上,使用throws关键字来进行异常标注。当方法被调用时需要对异常进行捕获。
public class ThrowsException {
public static void main(String args[]){
try{
System.out.println(div(10,0));
}catch(Exception e){
e.printStackTrace();
}
}
public static int div(int x,int y)throws ArithmeticException{
return x/y;
}
}
但是实际上调用此方法的方法(例如主方法)也可以继续向上抛出异常。
public class ThrowsException {
public static void main(String args[])throws ArithmeticException{
System.out.println(div(10,0));
}
public static int div(int x,int y)throws ArithmeticException{
return x/y;
}
}
throw关键字
此关键字的作用是手工进行异常抛出,即将手工产生一个实例化对象,并且进行异常的抛出处理。
public class ThrowException {
public static void main(String args[]){
try{
throw new Exception("手工抛出的异常!~");
}catch(Exception e){
e.printStackTrace();
}
}
}
请解释throw与throws的区别:
throw:是在代码中使用,主要是手工进行异常的抛出。
throws:是在方法定义上使用,表示将此方法可能产生的异常明确告诉给调用处,由调用处进行处理。
异常处理模型
public class ThrowsException {
public static void main(String args[]){
try{
System.out.println(MyMath.div(10,0));
}catch(Exception e){
e.printStackTrace();
}
}
}
class MyMath{
public static int div(int x,int y)throws Exception{
int temp=0;
System.out.print("******start(eg.net connecting)******");
// try{
// temp=x/y;
// }catch(Exception e){
// throw e;//这里可以不处理,但是要向上抛异常
// }finally{
// System.out.print("******end******");
// }
//简化操作
try{
temp=x/y;
}finally{
System.out.print("******end******");
}
return temp;
}
}
在以后资源访问时,很重要。
RuntimeException
public class ThrowsTest {
public static void main(String args[]){
int num=Integer.parseInt("123");
System.out.println(num);
}
}
//关于Integer类的parseInt()方法声明如下:
//public static int parseInt(String s)throws NumberFormatException
这个方法明确抛出了一个异常,但是处理的时候并没有强制性要求处理,为什么?
为了编码方便,提供有一个灵活可选的异常处理父类“RuntimeException”,其子类可以不用强制性处理。
请解释RuntimeException与Exception的区别,请举例
RuntimeException是Exception的子类。
RuntimeException的子类可以不要求强制性处理,而Exception的子类需要强制性处理
例:NumberFormatException,ClassCastException,NullPointerException
自定义异常类
有两种实现方案:1.继承Exception
class CustomException extends Exception{
public CustomException(String content){
super(content);
}
}
class Connection{
private static boolean statu=false;
public static void call()throws CustomException{
if(statu==false){
throw new CustomException("connection fail");
}else{
System.out.println("please tall");
}
}
}
public class CustomTest{
public static void main(String args[])throws Exception{
Connection.call();
}
}
2.继承RuntimeException
class CustomException extends RuntimeException{
public CustomException(String content){
super(content);
}
}
class Connection{
private static boolean statu=false;
public static void call()throws CustomException{
if(statu==false){
throw new CustomException("connection fail");
}else{
System.out.println("please tall");
}
}
}
public class CustomTest{
public static void main(String args[]){
Connection.call();
}
}
注:如果代码中报错,最好通过查询了解异常原因。
assert关键字
jdk1.4后出现了断言的功能(程序执行到某处时,一定是期待的结果。)
断言并不一定是准确的,可能有偏差,但这种偏差不影响程序正常执行。
如果要想执行断言,必须在程序执行的时候加入参数:-ea(enable)
例: java -ea *.class
java中并没有将断言设置为必须执行的步骤,需要在特定环境下开启。
断言的使用:
public class AssertTest {
public static void main(String args[]){
int x=10;
//操作
assert x==100 : "断言失败";//断言的使用
System.out.println(x);
}
}