异常的影响
异常是导致我们程序中断的指令流,但是程序中出现异常,就会导致程序终止执行,
范例:观察没有异常产生的程序
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 System.out.println("【2】数学计算:"+(10/2)); 5 6 System.out.println("【3】数字计算开始后"); 7 } 8 }
范例:观察产生异常
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 System.out.println("【2】数学计算:"+(10/0)); 5 System.out.println("【3】数字计算开始后"); 6 } 7 }
异常的处理
try(){
有可能出现异常的语句;
}[catch(异常类 对象){
异常的处理语句;
}catch(异常类 对象){
异常的处理语句;
}...][finally{
异常的统一出口;
}]
对于以上的关键字,可以出现的组合:try...catch,try...finally,try...catch...finally
范例:对异常的处理
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 try{ 5 System.out.println("【2】数学计算:"+(10/0)); 6 }catch(ArithmeticException e){ 7 System.out.println("【CATCH】异常已经被处理了"); 8 } 9 System.out.println("【3】数字计算开始后"); 10 } 11 }
发现出现异常后,整个程序就抛出一个异常。上面确实已经解决,但是里面会存在一个严重的问题。也就是你现在根本就不知道就产生什么呀的异常,所以为了明确取得异常的信息,可以直接输出异常对象,或者调用所有异常类中提供的printStackTrace()方法进行完整异常信息的输出。
范例:取得异常完整信息
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 try{ 5 System.out.println("【2】数学计算:"+(10/0)); 6 }catch(ArithmeticException e){ 7 e.printStackTrace(); 8 } 9 System.out.println("【3】数字计算开始后"); 10 } 11 }
在进行异常处理的时候还可以使用try..catch..finally
范例:观察try.catch..finally类的操作
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 try{ 5 System.out.println("【2】数学计算:"+(10/0)); 6 }catch(ArithmeticException e){ 7 e.printStackTrace(); 8 }finally{ 9 System.out.println("【FINALLY】不管是否有异常都一定要执行此语句。"); 10 } 11 System.out.println("【3】数字计算开始后"); 12 } 13 }
不管此时是否有异常, 最终都会执行finally类的代码
以上的程序是直接固定好了两个数字来进行除法计算,现在希望通过初始化参数,来进行计算;
范例:接受参数进行计算,
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 try{ 5 int x=Integer.parseInt(args[0]); 6 int y=Integer.parseInt(args[1]); 7 System.out.println("【2】数学计算:"+(x/y)); 8 }catch(ArithmeticException e){ 9 e.printStackTrace(); 10 }finally{ 11 System.out.println("【FINALLY】不管是否有异常都一定要执行此语句。"); 12 } 13 System.out.println("【3】数字计算开始后"); 14 } 15 }
用户执行的时候没有输入参数: java.lang.ArrayIndexOutOfBoundsException
用户执行的时候输入的参数不是数字:NumberFormatException
被除数为0:java Newbegin 10 0
通过以上代码可以发现,用catch捕获异常的时候,如果没有捕获指令的异常,那么程序依然无法进行处理。所有现在最直白的解决方案就使用多个catch:
1 public class Newbegin{ 2 public static void main(String args []) { 3 System.out.println("【1】数字计算开始前"); 4 try{ 5 int x=Integer.parseInt(args[0]); 6 int y=Integer.parseInt(args[1]); 7 System.out.println("【2】数学计算:"+(x/y)); 8 }catch(ArithmeticException e){ 9 e.printStackTrace(); 10 }catch(ArrayIndexOutOfBoundsException e){ 11 e.printStackTrace(); 12 }catch(NumberFormatException e){ 13 e.printStackTrace(); 14 }finally{ 15 System.out.println("【FINALLY】不管是否有异常都一定要执行此语句。"); 16 } 17 System.out.println("【3】数字计算开始后"); 18 } 19 }
如果现在真这么写,真这么测试,不怎么写也一样。用if..else也可以,以上代码,就是告诉你简单的流程,怎么使用try..catch ..finally
throws关键字
在进行方法的定义的时候,如果要告诉调用这本方法产生哪些异常,已经可以视同throws声明,如果该方法出现问题后不希望进行处理,就使用throws抛出。
范例:定义一个throws
1 class MyMath{ 2 //此处明确告诉用户该方法上会有异常 3 public static int div(int x,int y) throws Exception{ 4 return x/y; 5 } 6 } 7 public class Newbegin{ 8 public static void main(String args []) { 9 try{ 10 System.out.println(MyMath.div(10,2)); 11 }catch(Exception e){ 12 e.printStackTrace(); 13 } 14 } 15 }
如果你现在调用了throws声明的方法,那么在调用时就明确的使用try..catch进行异常捕获,因为该方法有可能产生异常,所以代码上要try..catch..finally
主方法本身也属于一个方法,所以出方法也可使用throws将异常抛出,这个时候如果产生了异常就会JVM进行处理。
1 class MyMath{ 2 //此处明确告诉用户该方法上会有异常 3 public static int div(int x,int y) throws Exception{ 4 return x/y; 5 } 6 } 7 public class Newbegin{ 8 public static void main(String args []) throws Exception{ 9 System.out.println(MyMath.div(10,0)); 10 } 11 }
你们在以后所编写的代码里面一定要斟酌好产生的异常,因为面对未知的程序类。如果要进行异常的处理,就要知道多少种异常,
throw关键字
throw是直接编写在语句之中的,表示人为的异常的抛出,例如,在之前使用过了一个10/0这样的语句,执行之后所产生的数学异常是由JVM负责进行异常类对象实例化了,而现在如果不希望异常类由系统产生,而是由用户来控制异常类实例化对象来产生,就可以使用throw来完成,
范例:使用throw产生异常类对象
1 class MyMath{ 2 //此处明确告诉用户该方法上会有异常 3 public static int div(int x,int y) throws Exception{ 4 return x/y; 5 } 6 } 7 public class Newbegin{ 8 public static void main(String args[]){ 9 try{ 10 throw new Exception("老子 ");//实例化对象 11 }catch(Exception e){ 12 e.printStackTrace(); 13 } 14 15 } 16 }
一般而言throw和break,continue,return一样都需要if判断使用,
请解释throw和throws的区别?
throw:方法内部主要表示进行手工的异常抛 出
throws:主要在方法声明上使用,明确的告诉用户本方法可能产生的异常,同时该方法可能不处理此异常。
异常处理标准格式:
现在为止异常中的所有核心概念都掌握了:try,catch,finally,throw,throws。
现在要求编写一个方法--进行除法操作,但是对于此方法要求如下
在进行除法计算操作之前首先要打印一行语句;
如果在除法计算的过程之中出现有错误,则应该将异常返回给调用处;
不管最终是否有错误 产生,都要求打印一行计算结束的信息;
范例:观察程序的实现
1 class MyMath{ 2 //如果该方法不进行异常的处理,一定要throw抛出 3 public static int div(int x,int y) throws Exception{ 4 int result=0; 5 System.out.println("【开始】进行除法计算"); 6 try{ 7 result=x/y;//此处有异常,后面不执行 8 }catch(Exception e){ 9 throw e; 10 }finally{ 11 System.out.println("【结束】除 法计算完毕"); 12 } 13 return result; 14 } 15 } 16 public class Newbegin{ 17 public static void main(String args[]){ 18 try{ 19 System.out.println(MyMath.div(10,0)); 20 }catch(Exception e){ 21 e.printStackTrace(); 22 } 23 } 24 }
当然,对于以上的格式还可以进一步简化 :直接使用try...finally。
1 class MyMath{ 2 //如果该方法不进行异常的处理,一定要throw抛出 3 public static int div(int x,int y) throws Exception{ 4 int result=0; 5 System.out.println("【开始】进行除法计算"); 6 try{ 7 result=x/y;//此处有异常,后面不执行 8 }finally{ 9 System.out.println("【结束】除 法计算完毕"); 10 } 11 return result; 12 } 13 } 14 public class Newbegin{ 15 public static void main(String args[]){ 16 try{ 17 System.out.println(MyMath.div(10,0)); 18 }catch(Exception e){ 19 e.printStackTrace(); 20 } 21 } 22 }
RuntimeException类()
1 public class Newbegin{ 2 public static void main(String args[]){ 3 String str="100"; 4 int num=Integer.parseInt(str); 5 System.out.println(num*2); 6 }}
于是来观察一下Integer类中关于parseInt()方法的定义
public static int parseInt(String s) throws NumberFormatException
这个方法上已经明确的抛出了一个异常,但是在进行调用的时候发现,没有进行异常的处理,也可以正常执行,这个是RuntimeException的范畴,来观察NumberFormatException的继承结构:
解释Exception与RuntimeException的区别?请列举出几个常见的RuntimeException
Exception是RuntimeException的父类,使用Exception定义的异常都要求必须使用异常处理
RuntimeException可以由用户选择性的来进行异常的处理,
ClassCastException ArithmeticException NullPointerException
异常的捕获与处理(断言)assert
断言是从JDK1.4开始引入的概念,所谓断言的概念指的是当程序执行到某些语句之后,其数据的内容一定是约定的内容。
范例:观察断言
1 public class Newbegin{ 2 public static void main(String args[]){ 3 int num=100; 4 //中间可能进过很多的步骤,预计Num的内容应该变为300 5 assert num==300:"错误:num的内容不是300"; 6 System.out.println(num); 7 } 8 }
这个作为了解,java中的这个和c++的很贴近
自定义异常类
在java里面实际上针对可能出现的公共的程序问题提供相应的异常信息,但是很多时候这个异常信息往往不够我们自己使用的,例如:现在在进行加法处理的时候,如果发现两个内容的相加结果为30,那么就应该抛出一个AddException异常。但是这种异常java是不会提供,所有我们要定义一个自己的异常。
就要定义属于自己的异常类继承两种父类:Exception,RuntimeException
范例:实现自定义异常类
1 class AddException extends Exception{ 2 public AddException(String msg){ 3 super(msg); 4 } 5 } 6 public class Newbegin{ 7 public static void main(String args[]) throws Exception{ 8 if((10+20)==30){ 9 throw new AddException("错误的相加操作"); 10 } 11 } 12 }
一般做系统设计的时候一定会牵扯到与你业务有关的异常问题,
以后有错误上www.googlec.com http://stackoverflow.com/
对于异常不要去刻意的使用,因为随着学习,很多时候你自己就会知道哪里该用异常处理了、
1.异常的处理流程
2.异常的处理格式
3.异常处理的模型