异常处理的目的是依据实际情况提供不同的错误应对策略与手段,使程序更稳定,更安全。
异常处理的主要用途是提供准确的错误消息,解释失败的原因、位置和错误类型等,同时提供一定的恢复能力,尽可能地保证数据完整性不被破坏,并让程序能继续运行。
Try{
//可能发生运行错误的代码;
}
catch(异常类型 异常对象引用){
//用于处理异常的代码
}
finally{
//用于“善后” 的代码
}
把可能会发生错误的代码放进try语句块中。
当程序检测到出现了一个错误时会抛出一个异常对象。异常处理代码会捕获并处理这个错误。
catch语句块中的代码用于处理错误。
当异常发生时,程序控制流程由try语句块跳转到catch语句块。
不管是否有异常发生,finally语句块中的语句始终保证被执行。
如果没有提供合适的异常处理代码,JVM将会结束掉整个应用程序。
Throwable类有两个直接子类:
Exception:出现的问题是可以被捕获的;
Error:系统错误,通常由JVM处理。
可捕获的异常又可以分为两类:
(1)Check异常:直接派生自Exception的异常类,必须被捕获或再次声明抛出
(2)Runtime异常:派生自RuntimeException的异常类。使用throw语句可以随时抛出这种异常对象:
throw new ArithmeticException(…);
异常的“多态”特性
可以有多个catch语句块,每个代码块捕获一种异常。在某个try块后有两个不同的catch 块捕获两个相同类型的异常是语法错误。
使用catch语句,只能捕获Exception类及其子类的对象。因此,一个捕获Exception对象的catch语句块可以捕获所有“可捕获”的异常。
将catch(Exception e)放在别的catch块前面会使这些catch块都不执行,因此Java不会编译这个程序。
“finally”的功用
资源泄露:当一个资源不再被某应用程序使用,但此程序并未向系统声明不再使用此资源时发生这种情况
finally语句块主要用于解决资源泄露问题,它位于catch语句块之后,JVM保证它们一定执行。
注意:finally语句块中也可能发生异常,如果这种情况发生,先前的异常被放弃。
特别注意:
当有多层嵌套的finally时,异常在不同的层次抛出 ,在不同的位置抛出,可能会导致不同的finally语句块执行顺序。
如何跟踪异常的传播路径?
当程序中出现异常时,JVM会依据方法调用顺序依次查找有关的错误处理程序。
可使用printStackTrace 和 getMessage方法了解异常发生的情况:
printStackTrace:打印方法调用堆栈。
每个Throwable类的对象都有一个getMessage方法,它返回一个字串,这个字串是在Exception构造函数中传入的,通常让这一字串包含特定异常的相关信息。
更新后的模拟ATM
1 import javax.swing.JOptionPane; 2 /*** 3 * 4 * @author 吕鹏博 5 * 6 */ 7 class Account 8 { 9 10 String account,name; 11 int mima,money; 12 Account(String account,String name,int mima,int money) 13 { 14 this.account=account; 15 this.name=name; 16 this.mima=mima; 17 this.money=money; 18 } 19 public void setaccount(String a) 20 { 21 this.account=a; 22 } 23 public String getaccount() 24 { 25 return this.account; 26 } 27 public void setname(String a) 28 { 29 this.name=a; 30 } 31 public String getname() 32 { 33 return this.name; 34 } 35 public void setmima(int a) 36 { 37 this.mima=a; 38 } 39 public int getmima() 40 { 41 return this.mima; 42 } 43 44 public void setmoney(int a) 45 { 46 this.money=a; 47 } 48 public int getmoney() 49 { 50 return this.money; 51 } 52 53 } 54 class MyException extends Exception{ 55 56 public MyException(String e){ 57 super(e); 58 } 59 } 60 class AccountManage 61 { 62 63 static Account o=new Account("951654321", "xiaohua",123456, 5000); 64 //默认账户:"951654321", "xiaohua",123456, 5000; 65 public static void get() throws MyException{//取款 66 String b,b3;int b1 = 0,b2=0; 67 68 String output="1.100元\n2.500元\n" 69 + "3.1000元\n4.1500元\n5.2000元\n6.5000元\n7.其他金额\n8.退出\n请输入1至8的选项。"; 70 try{ 71 b=JOptionPane.showInputDialog(output); 72 b1=Integer.parseInt(b); 73 if(b1<1||b1>8) 74 { 75 MyException e=new MyException("未输入正确选项,请重试。"); 76 throw e;} 77 } 78 79 catch(MyException e){ 80 System.out.println(e); 81 } 82 finally{ 83 84 switch(b1) 85 { 86 87 case 1: 88 if(o.getmoney()>100){ 89 o.setmoney(o.getmoney()-100); 90 output="取款成功,余额"+o.getmoney(); 91 }else{output="余额不足,退出。";} 92 break; 93 case 2: 94 if(o.getmoney()>500){ 95 o.setmoney(o.getmoney()-500);output="取款成功,余额"+o.getmoney();} 96 else { 97 output="余额不足,退出。";} 98 break; 99 case 3: 100 if(o.getmoney()>1000){ 101 o.setmoney(o.getmoney()-500); 102 output="取款成功,余额"+o.getmoney(); 103 } 104 else 105 {output="余额不足,退出。";} 106 break; 107 case 4: 108 if(o.getmoney()>1500){ 109 o.setmoney(o.getmoney()-1500);output="取款成功,余额"+o.getmoney();} 110 else {output="余额不足,退出。";} 111 break; 112 case 5: 113 if(o.getmoney()>2000){ 114 o.setmoney(o.getmoney()-2000);output="取款成功,余额"+o.getmoney();} 115 else {output="余额不足,退出。";} 116 break; 117 case 6:if(o.getmoney()>5000){ 118 o.setmoney(o.getmoney()-5000);output="取款成功,余额"+o.getmoney();} 119 else {output="余额不足,退出。";} 120 break; 121 case 7: 122 try{ 123 b3=JOptionPane.showInputDialog("请输入所取金额"); 124 if(!num(b3)){ 125 MyException sq=new MyException("请输入正确的数字"); 126 throw sq;} 127 128 try{ 129 if(b3.equals(‘A‘)){ 130 MyException w=new MyException("余额不足."); 131 throw w;} 132 try{ 133 b2=Integer.parseInt(b3); 134 if((b2%100)!=0){//判断b2的值是否为100的倍数 135 MyException q=new MyException("录入错误,请输出100的整数倍.");throw q;} 136 } 137 catch(MyException q){System.out.println(q);} 138 if(o.getmoney()>b2){ 139 o.setmoney(o.getmoney()-b2);output="取款成功,余额"+o.getmoney();} 140 else {output="余额不足,退出。";}} 141 catch(MyException w){ 142 System.out.println(w);} 143 } 144 catch(MyException sq){ 145 System.out.println(sq);} 146 147 148 break; 149 default:break;} 150 151 152 JOptionPane.showMessageDialog(null, output); 153 } 154 } 155 156 157 158 159 public static boolean num(String value){ //一个静态方法,判断你输入的是不是数字 160 try { 161 Integer.parseInt(value); 162 return true; 163 } catch (Exception e) { 164 return false; 165 } 166 } 167 public void Cunkuan() throws MyException 168 { 169 int b2; 170 String b3; 171 try{ 172 b3=JOptionPane.showInputDialog("请输入存款金额"); 173 b2=Integer.parseInt(b3); 174 if(b2<0&&b2%100!=0) 175 { 176 throw new MyException("不能输入比零小的数,请重新输入。"); 177 } 178 o.setmoney(o.getmoney()+b2); 179 System.out.println("存款成功。你的余额为:"+o.getmoney()); 180 181 182 } 183 catch(MyException e){ 184 System.out.println(e); 185 } 186 187 188 } 189 public void zhuanzhang() 190 { 191 String b3=JOptionPane.showInputDialog("请输入转账账户"); 192 String b2=JOptionPane.showInputDialog("请输入转账金额"); 193 int d=Integer.parseInt(b2); 194 o.setmoney(o.getmoney()+d); 195 System.out.println("转账成功。你的余额为:"+o.getmoney()); 196 197 } 198 public boolean checkPassword(int a){ 199 if(a==123456){return true;} 200 else{return false;} 201 } 202 203 204 } 205 206 public class Atm { 207 208 209 public static void main(String[] args) throws MyException { 210 211 AccountManage p=new AccountManage(); 212 String b3=""; 213 int b2=0; 214 String output=""; 215 String s1=""; 216 int i=0; 217 int s2; 218 output="请插入您的银行卡:\n"+"已插入卡,插入后请不要移动您的卡,谢谢配合!\n"+"正在识别请稍后"; 219 JOptionPane.showMessageDialog(null, output); 220 boolean p0=true; 221 while(p0) 222 { 223 224 try{ 225 output="\t------>"; 226 output+="\n卡识别正确,进入业务操作界面!"; 227 JOptionPane.showMessageDialog(null, output); 228 for( i=0;i<3;i++) 229 { 230 s1=JOptionPane.showInputDialog("请输入密码。"); 231 s2=Integer.parseInt(s1); 232 boolean flag=p.checkPassword(s2); 233 if(flag) 234 { 235 operate(p,b3,b2); 236 } 237 } 238 if(i==3){ 239 MyException sd=new MyException("您已经输入密码错误超过3次,该卡已被锁定!"); 240 p0=false; 241 throw sd;} 242 } 243 catch(MyException sd){System.out.println(sd);} 244 } 245 246 } 247 public static void operate(AccountManage p,String b3,int b2 ){ 248 System.out.println("密码正确:进入操作界面"); 249 b3=JOptionPane.showInputDialog("此账户默认金额为100\n请输入选项,\n1.存款\n2.取款\n3.转账\n4.退出"); 250 b2=Integer.parseInt(b3); 251 while(b2!=4){ 252 try{ 253 switch(b2) 254 { 255 case 1: 256 p.Cunkuan(); 257 break; 258 259 case 2: 260 p.get(); 261 break; 262 case 3: 263 p.zhuanzhang(); 264 break;} 265 b3=JOptionPane.showInputDialog("请输入选项,\n1.存款\n2.取款\n3.转账\n4.退出"); 266 b2=Integer.parseInt(b3); 267 if(b2<0||b2>4){ 268 MyException a=new MyException("输入错误,请重新输入。"); 269 throw a;} 270 }catch(MyException a){ 271 System.out.println(a); 272 } 273 } 274 } 275 }
NEW ATM
实验截图: