异常是指由于程序中的错误而导致正常的程序流程中断的一种事件。
1.没有错误处理的程序:
{
openTheFile;
determine its size;
allocate that much memory;
read-file
closeTheFile;
}
2.以常规方法处理错误:
openFiles;
if (theFilesOpen)
{
determine the length of the file;
if (gotTheFileLength)
{
allocate that much memory;
if (gotEnoughMemory)
{
read the file into memory;
if (readFailed) errorCode=-1;
else errorCode = -2;
}
else errorCode=-3;
}
else errorCode=-4 ;
}
else errorCode=-5;
以常规方法处理错误存在的问题:
观察前面的程序,大家会发现大部分精力花在出错处理上了
只把能够想到的错误考虑到,对以外的情况无法处理
程序可读性差,大量的错误处理代码混杂在程序中
出错返回信息量太少,无法更确切的了解错误状况或原因
3.用异常的形式处理错误:
{
try
{
openTheFile;
determine its size;
allocate that much memory;
read-File;
closeTheFile;
}
catch(fileopenFailed) { dosomething; }
catch(sizeDetermineFailed) { dosomething; }
catch(memoryAllocateFailed) { dosomething; }
catch(readFailed) { dosomething; }
catch(fileCloseFailed) { dosomething; }
finally { dosomething; }
}
异常机制的优点:
把错误处理代码从常规代码中分离出来
按错误类型和差别分组(类Exception,派生)
对无法预测的错误的捕获和处理(基类)
克服了传统方法的错误信息有限的问题(getMessage)
把错误传播给调用堆栈(比较:全局变量,返回值)
什么情况下使用异常机制?
当方法因为自身无法控制的原因而不能完成其任务
(文件不存在,网络连接无法建立……
处理在方法、类库、类中抛出的异常
( 如FileInputStream.read产生IOException
在大的项目中采用统一的方式处理错误时
( 如编写一个文字处理器
异常应该是不经常发生但却可能发生的故障
(一定发生的事件不应该用异常机制来处理
异常处理用于使系统从故障中恢复
( 提示信息/不产生无效的结果/释放资源
异常机制的关键步骤
try {…}
定义可能产生异常的代码段
catch (Etype e) {…}
用于捕获一个异常
finally {…}
用于做统一的事后处理,如释放资源
throw e;
用于抛出一个异常
throws Etype1, Etype2 ……
用于声明方法可能抛出的异常类型
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//STEP 2: Register JDBC driver
Class.forName("com.mysql.cj.jdbc.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//STEP 4: Set auto commit as false.
conn.setAutoCommit(false);
//STEP 5: Execute a query to delete statment with
// required arguments for RS example.
System.out.println("Creating statement...");
stmt = conn.createStatement();
//STEP 6: Now list all the available records.
String sql = "SELECT * FROM person2";
ResultSet rs = stmt.executeQuery(sql);
System.out.println("List result set for reference....");
printRs(rs);
// STEP 7: delete rows having ID grater than 104
// But save point before doing so.
Savepoint savepoint1 = conn.setSavepoint("ROWS_DELETED_1");
System.out.println("Deleting row....");
String SQL = "DELETE FROM person2 " +
"WHERE ID = 106";
stmt.executeUpdate(SQL);
// oops... we deleted too wrong employees!
//STEP 8: Rollback the changes afetr save point 2.
conn.rollback(savepoint1);
// STEP 9: delete rows having ID grater than 104
// But save point before doing so.
Savepoint savepoint2 = conn.setSavepoint("ROWS_DELETED_2");
System.out.println("Deleting row....");
SQL = "DELETE FROM person2 " +
"WHERE ID = 107";
stmt.executeUpdate(SQL);
//STEP 10: Now list all the available records.
sql = "SELECT * FROM person2";
rs = stmt.executeQuery(sql);
System.out.println("List result set for reference....");
printRs(rs);
//STEP 10: Clean-up environment
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
// If there is an error then rollback the changes.
System.out.println("Rolling back data here....");
try{
if(conn!=null)
conn.rollback();
}catch(SQLException se2){
se2.printStackTrace();
}//end try
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
}//end main