十五分钟的层层递进
要编写一个根据成绩判断成绩优劣的程序很简单,但要做到健壮性确实需要考虑很多。
——你没有限制客户的请求,所以客户是自由的。
在课上不到半小时完成的这次小程序,不得不说确实对我很有帮助,最后完成的代码就往下放了。
package test; import java.math.BigDecimal; import java.util.Scanner; public class Test { private BigDecimal num; public Test() { num = new BigDecimal(0); } public void judge() { Scanner in = new Scanner(System.in); System.out.println("输入:"); String b = in.nextLine(); try { Double.parseDouble(b); num = new BigDecimal(b); if (0 <= num.intValue() && num.intValue() < 60) System.out.println("不及格"); else if (0 < num.intValue() && num.intValue() < 70) System.out.println("及格"); else if (0 < num.intValue() && num.intValue() < 80) System.out.println("中"); else if (0 < num.intValue() && num.intValue() < 90) System.out.println("良"); else if (0 < num.intValue() && num.intValue() <= 100) System.out.println("优"); if (num.intValue() < 0 || num.intValue() > 100) System.out.println("数值错误"); } catch (NumberFormatException e) { System.out.println("非法数字"); } finally { in.close(); } } public static void main(String[] args) { Test a = new Test(); a.judge(); } }
动手动脑——Java异常处理
import javax.swing.*; class AboutException { public static void main(String[] a) { int i=1, j=0, k; k=i/j; try { k = i/j; // Causes division-by-zero exception //throw new Exception("Hello.Exception!"); } catch ( ArithmeticException e) { System.out.println("被0除. "+ e.getMessage()); } catch (Exception e) { if (e instanceof ArithmeticException) System.out.println("被0除"); else { System.out.println(e.getMessage()); } } finally { JOptionPane.showConfirmDialog(null,"OK"); } } }
这个代码直接执行是默认的异常显示,注释掉第一个k=i/j,显示“被0除. / by zero”,由此可见Java处理异常的机制——
- JVM会结束没有处理异常代码的应用程序;
- 把可能出错的代码放到try语句块中;
- 把处理异常的代码放catch语句块中;
- 异常发生,流程由try跳转到catch(异常后的代码不会执行)
- 不管是否有异常发生,finally语句块中的语句始终保证被执行。用来处理程序无论如何都要做的事(输入流的关闭之类的)
异常都是由Throwable类继承而来,之后分为Error——系统错误、Exception,系统错误没法考虑,而后者又分为RuntimeException和IOException,一个是程序错误导致的异常,一个是其他问题(像文件不存在之类的),前者是程序设计问题,后者不一定是你的问题,但都是必须处理的问题。
奇怪的现象
int i=1, j=0, k;
k=i/j;
这个会报错毋庸置疑。但……
double d1=100,d2=0,result;
result=d1/d2;
System.out.println("浮点数除以零:" + data);
这个不会报错!因为double 0实际上是个很接近于0的数,相除后能得到数,所以Java引入Infinity概念来表示这种情况。
动手动脑:多层的异常捕获
public class CatchWho { public static void main(String[] args) { try { try { throw new ArrayIndexOutOfBoundsException(); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); } throw new ArithmeticException(); } catch(ArithmeticException e) { System.out.println("发生ArithmeticException"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); } } }
结果
ArrayIndexOutOfBoundsException/内层try-catch
发生ArithmeticException
内层抛出的ArrayIndexOutOfBoundsException已经被处理,所以不会引发外部catch,而是处理更明显的ArithmeticException。
public class CatchWho2 { public static void main(String[] args) { try { try { throw new ArrayIndexOutOfBoundsException(); } catch(ArithmeticException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); } throw new ArithmeticException(); } catch(ArithmeticException e) { System.out.println("发生ArithmeticException"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); } } }
结果
ArrayIndexOutOfBoundsException/外层try-catch
内层抛出的ArrayIndexOutOfBoundsException没被处理,所以比ArithmeticException更明显,而前者被处理后就不会处理ArithmeticException了。
动手动脑——多层finally
public class EmbededFinally { public static void main(String args[]) { int result; try { System.out.println("in Level 1"); try { System.out.println("in Level 2"); // result=100/0; //Level 2 try { System.out.println("in Level 3"); result = 100 / 0; // Level 3 } catch (Exception e) { System.out.println("Level 3:" + e.getClass().toString()); } finally { System.out.println("In Level 3 finally"); } // result=100/0; //Level 2 } catch (Exception e) { System.out.println("Level 2:" + e.getClass().toString()); } finally { System.out.println("In Level 2 finally"); } // result = 100 / 0; //level 1 } catch (Exception e) { System.out.println("Level 1:" + e.getClass().toString()); } finally { System.out.println("In Level 1 finally"); } } }
不加注释的结果
in Level 1
in Level 2
Level 2:class java.lang.ArithmeticException
In Level 2 finally
Level 1:class java.lang.ArithmeticException
In Level 1 finally
注释第一个
in Level 1
in Level 2
in Level 3
Level 3:class java.lang.ArithmeticException
In Level 3 finally
Level 2:class java.lang.ArithmeticException
In Level 2 finally
Level 1:class java.lang.ArithmeticException
In Level 1 finally
注释第二个
in Level 1
in Level 2
in Level 3
In Level 3 finally
Level 2:class java.lang.ArithmeticException
In Level 2 finally
Level 1:class java.lang.ArithmeticException
In Level 1 finally
注释第三个
in Level 1
in Level 2
in Level 3
In Level 3 finally
In Level 2 finally
Level 1:class java.lang.ArithmeticException
In Level 1 finally
注释最后一个
in Level 1
in Level 2
in Level 3
In Level 3 finally
In Level 2 finally
In Level 1 finally
另外,遇到“System.exit(0);”后,finally也不一定执行。
下面直接总结(复制)课件内容——