Java—異常處理總結

異常處理是程序設計中一個很是重要的方面,也是程序設計的一大難點,從C開始,你也許已經知道如何用if...else...來控制異常了,也許是自發的,然而這種控制異常痛苦,同一個異常或者錯誤若是多個地方出現,那麼你每一個地方都要作相同處理,感受至關的麻煩!html

  Java語言在設計的當初就考慮到這些問題,提出異常處理的框架的方案,全部的異常均可以用一個類型來表示,不一樣類型的異常對應不一樣的子類異常(這裏的異常包括錯誤概念),定義異常處理的規範,在1.4版本之後增長了異常鏈機制,從而便於跟蹤異常!這是Java語言設計者的高明之處,也是Java語言中的一個難點,下面是我對Java異常知識的一個總結,也算是資源回收一下。java

  1、Java異常的基礎知識程序員

  異常是程序中的一些錯誤,但並非全部的錯誤都是異常,而且錯誤有時候是能夠避免的。好比說,你的代碼少了一個分號,那麼運行出來結果是提示是錯誤java.lang.Error;若是你用System.out.println(11/0),那麼你是由於你用0作了除數,會拋出java.lang.ArithmeticException的異常。web

  有些異常須要作處理,有些則不須要捕獲處理,後面會詳細講到。sql

  天有不測風雲,人有旦夕禍福,Java的程序代碼也如此。在編程過程當中,首先應當儘量去避免錯誤和異常發生,對於不可避免、不可預測的狀況則在考慮異常發生時如何處理。數據庫

  Java中的異經常使用對象來表示。Java對異常的處理是按異常分類處理的,不一樣異常有不一樣的分類,每種異常都對應一個類型(class),每一個異常都對應一個異常(類的)對象。apache

  異常類從哪裏來?有兩個來源,一是Java語言自己定義的一些基本異常類型,二是用戶經過繼承Exception類或者其子類本身定義的異常。Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。編程

  異常的對象從哪裏來呢?有兩個來源,一是Java運行時環境自動拋出系統生成的異常,而無論你是否願意捕獲和處理,它總要被拋出!好比除數爲0的異常。二是程序員本身拋出的異常,這個異常能夠是程序員本身定義的,也能夠是Java語言中定義的,用throw 關鍵字拋出異常,這種異經常用來向調用者彙報異常的一些信息。api

  異常是針對方法來講的,拋出、聲明拋出、捕獲和處理異常都是在方法中進行的。數組

  Java異常處理經過5個關鍵字try、catch、throw、throws、finally進行管理。基本過程是用try語句塊包住要監視的語 句,若是在try語句塊內出現異常,則異常會被拋出,你的代碼在catch語句塊中能夠捕獲到這個異常並作處理;還有以部分系統生成的異常在Java運行 時自動拋出。你也能夠經過throws關鍵字在方法上聲明該方法要拋出異常,而後在方法內部經過throw拋出異常對象。finally語句塊會在方法執 行return以前執行,通常結構以下:

  try{

  程序代碼

  }catch(異常類型1 異常的變量名1){

  程序代碼

  }catch(異常類型2 異常的變量名2){

  程序代碼

  }finally{

  程序代碼

  }

  catch語句能夠有多個,用來匹配多個異常,匹配上多箇中一個後,執行catch語句塊時候僅僅執行匹配上的異常。catch的類型是Java語言 中定義的或者程序員本身定義的,表示代碼拋出異常的類型,異常的變量名錶示拋出異常的對象的引用,若是catch捕獲並匹配上了該異常,那麼就能夠直接用 這個異常變量名,此時該異常變量名指向所匹配的異常,而且在catch代碼塊中能夠直接引用。這一點很是很是的特殊和重要!

  Java異常處理的目的是提升程序的健壯性,你能夠在catch和finally代碼塊中給程序一個修正機會,使得程序不因異常而終止或者流程發生以 外的改變。同時,經過獲取Java異常信息,也爲程序的開發維護提供了方便,通常經過異常信息就很快就能找到出現異常的問題(代碼)所在。

  Java異常處理是Java語言的一大特點,也是個難點,掌握異常處理可讓寫的代碼更健壯和易於維護。

  2、Java異常類類圖

  下面是這幾個類的層次圖:

  java.lang.Object

     java.lang.Throwable

      java.lang.Exception

        java.lang.RuntimeException

          java.lang.Error

           java.lang.ThreadDeath

  下面四個類的介紹來自java api 文檔。

  一、Throwable

  Throwable 類是 Java 語言中全部錯誤或異常的超類。只有當對象是此類(或其子類之一)的實例時,才能經過 Java 虛擬機或者 Java throw 語句拋出。相似地,只有此類或其子類之一才能夠是 catch 子句中的參數類型。

  兩個子類的實例,Error 和 Exception,一般用於指示發生了異常狀況。一般,這些實例是在異常狀況的上下文中新近建立的,所以包含了相關的信息(好比堆棧跟蹤數據)。

  二、Exception

  Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件,表示程序自己能夠處理的異常。

  三、Error

  Error 是 Throwable 的子類,表示僅靠程序自己沒法恢復的嚴重錯誤,用於指示合理的應用程序不該該試圖捕獲的嚴重問題。

  在執行該方法期間,無需在方法中經過throws聲明可能拋出但沒有捕獲的 Error 的任何子類,由於Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即便沒有用try...catch語句捕獲它,也沒有用throws字句聲明拋出它,仍是會編譯經過。

  四、RuntimeException

  RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即便沒有用try...catch語句捕獲它,也沒有用throws字句聲明拋出它,仍是會編譯經過,這種異常能夠經過改進代碼實現來避免。

  五、ThreadDeath

  調用 Thread 類中帶有零參數的 stop 方法時,受害線程將拋出一個 ThreadDeath 實例。

  僅當應用程序在被異步終止後必須清除時才應該捕獲這個類的實例。若是 ThreadDeath 被一個方法捕獲,那麼將它從新拋出很是重要,由於這樣才能讓該線程真正終止。

  若是沒有捕獲 ThreadDeath,則頂級錯誤處理程序不會輸出消息。

  雖然 ThreadDeath 類是「正常出現」的,但它只能是 Error 的子類而不是 Exception 的子類,由於許多應用程序捕獲全部出現的 Exception,而後又將其放棄。

  以上是對有關異常API的一個簡單介紹,用法都很簡單,關鍵在於理解異常處理的原理,具體用法參看Java API文檔。

  3、Java異常處理機制

  對於可能出現異常的代碼,有兩種處理辦法:

  第1、在方法中用try...catch語句捕獲並處理異常,catach語句能夠有多個,用來匹配多個異常。例如:

  

public void p(int x){
  try{
  ...
  }catch(Exception e){
  ...
  }finally{
  ...
  }
  }

  第2、對於處理不了的異常或者要轉型的異常,在方法的聲明處經過throws語句拋出異常。例如:

 

  

public void test1() throws MyException{
  ...
  if(....){
  throw new MyException();
  }
  }

   若是每一個方法都是簡單的拋出異常,那麼在方法調用方法的多層嵌套調用中,Java虛擬機會從出現異常的方法代碼塊中往回找,直到找處處理該異常的代碼塊 爲止。而後將異常交給相應的catch語句處理。若是Java虛擬機追溯到方法調用棧最底部main()方法時,若是仍然沒有找處處理異常的代碼塊,將按 照下面的步驟處理:

 

  第1、調用異常的對象的printStackTrace()方法,打印方法調用棧的異常信息。

  第2、若是出現異常的線程爲主線程,則整個程序運行終止;若是非主線程,則終止該線程,其餘線程繼續運行。

  經過分析思考能夠看出,越早處理異常消耗的資源和時間越小,產生影響的範圍也越小。所以,不要把本身能處理的異常也拋給調用者。

  還有一點,不可忽視:finally語句在任何狀況下都必須執行的代碼,這樣能夠保證一些在任何狀況下都必須執行代碼的可靠性。好比,在數據庫查詢異 常的時候,應該釋放JDBC鏈接等等。finally語句先於return語句執行,而不論其前後位置,也無論是否try塊出現異常。finally語句 惟一不被執行的狀況是方法執行了System.exit()方法。System.exit()的做用是終止當前正在運行的 Java 虛擬機。finally語句塊中不能經過給變量賦新值來改變return的返回值,也建議不要在finally塊中使用return語句,沒有意義還容易 致使錯誤。

  最後還應該注意一下異常處理的語法規則:

  第1、try語句不能單獨存在,能夠和catch、finally組成 try...catch...finally、try...catch、try...finally三種結構,catch語句能夠有一個或多個,finally語句最多一個,try、catch、finally這三個關鍵字均不能單獨使用。

  第2、try、catch、finally三個代碼塊中變量的做用域分別獨立而不能相互訪問。若是要在三個塊中均可以訪問,則須要將變量定義到這些塊的外面。

  第3、多個catch塊時候,Java虛擬機會匹配其中一個異常類或其子類,就執行這個catch塊,而不會再執行別的catch塊。

  第4、throw語句後不容許有緊跟其餘語句,由於這些沒有機會執行。

  第5、若是一個方法調用了另一個聲明拋出異常的方法,那麼這個方法要麼處理異常,要麼聲明拋出。

  那怎麼判斷一個方法可能會出現異常呢?通常來講,方法聲明的時候用了throws語句,方法中有throw語句,方法調用的方法聲明有throws關鍵字。

  throw和throws關鍵字的區別

  throw用來拋出一個異常,在方法體內。語法格式爲:throw 異常對象。

  throws用來聲明方法可能會拋出什麼異常,在方法名後,語法格式爲:throws 異常類型1,異常類型2...異常類型n。

  4、如何定義和使用異常類

  一、使用已有的異常類,假如爲IOException、SQLException。

 

 try{
  程序代碼
  }catch(IOException ioe){
  程序代碼
  }catch(SQLException sqle){
  程序代碼
  }finally{
  程序代碼
  }

  二、自定義異常類

 

  建立Exception或者RuntimeException的子類便可獲得一個自定義的異常類。例如:

 

 public class MyException extends Exception{
  public MyException(){}
  public MyException(String smg){
  super(smg);
  }
  }

  三、使用自定義的異常

 

  用throws聲明方法可能拋出自定義的異常,並用throw語句在適當的地方拋出自定義的異常。例如:

  在某種條件拋出異常

 

  public void test1() throws MyException{
  ...
  if(....){
  throw new MyException();
  }
  }

  將異常轉型(也叫轉譯),使得異常更易讀易於理解

 

 

  public void test2() throws MyException{
  ...
  try{
  ...
  }catch(SQLException e){
  ...
  throw new MyException();
  }
  }

  還有一個代碼,頗有意思:

 

  

public void test2() throws MyException{
  ...
  try {
  ...
  } catch (MyException e) {
  throw e;
  }
  }

  這段代碼實際上捕獲了異常,而後又和盤托出,沒有一點意義,若是這樣還有什麼好處理的,不處理就好了,直接在方法前用throws聲明拋出不就得了。異常的捕獲就要作一些有意義的處理。

 

  5、運行時異常和受檢查異常

  Exception類能夠分爲兩種:運行時異常和受檢查異常。

  一、運行時異常

  RuntimeException類及其子類都被稱爲運行時異常,這種異常的特色是Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常 時,即便沒有用try...catch語句捕獲它,也沒有用throws字句聲明拋出它,仍是會編譯經過。例如,當除數爲零時,就會拋出 java.lang.ArithmeticException異常。

  二、受檢查異常

  除了RuntimeException類及其子類外,其餘的Exception類及其子類都屬於受檢查異常,這種異常的特色是要麼用try...catch捕獲處理,要麼用throws語句聲明拋出,不然編譯不會經過。

  三、二者的區別

  運行時異常表示沒法讓程序恢復運行的異常,致使這種異常的緣由一般是因爲執行了錯誤的操做。一旦出現錯誤,建議讓程序終止。

  受檢查異常表示程序能夠處理的異常。若是拋出異常的方法自己不處理或者不能處理它,那麼方法的調用者就必須去處理該異常,不然調用會出錯,連編譯也沒法經過。固然,這兩種異常都是能夠經過程序來捕獲並處理的,好比除數爲零的運行時異常:

 

  public class HelloWorld {
  public static void main(String[] args) {
  System.out.println("Hello World!!!");
  try{
  System.out.println(1/0);
  }catch(ArithmeticException e){
  System.out.println("除數爲0!");
  }
  System.out.println("除數爲零後程序沒有終止啊,呵呵!!!");
  }
  }
  運行結果:
  Hello World!!!
  除數爲0!
  除數爲零後程序沒有終止啊,呵呵!!!

  四、運行時錯誤

 

  Error類及其子類表示運行時錯誤,一般是由Java虛擬機拋出的,JDK中與定義了一些錯誤類,好比VirtualMachineError

  和OutOfMemoryError,程序自己沒法修復這些錯誤.通常不去擴展Error類來建立用戶自定義的錯誤類。而RuntimeException類表示程序代碼中的錯誤,是可擴展的,用戶能夠建立特定運行時異常類。

  Error(運行時錯誤)和運行時異常的相同之處是:Java編譯器都不去檢查它們,當程序運行時出現它們,都會終止運行。

  五、最佳解決方案

  對於運行時異常,咱們不要用try...catch來捕獲處理,而是在程序開發調試階段,儘可能去避免這種異常,一旦發現該異常,正確的作法就會改進程 序設計的代碼和實現方式,修改程序中的錯誤,從而避免這種異常。捕獲並處理運行時異常是好的解決辦法,由於能夠經過改進代碼實現來避免該種異常的發生。

  對於受檢查異常,沒說的,老老實實去按照異常處理的方法去處理,要麼用try...catch捕獲並解決,要麼用throws拋出!

  對於Error(運行時錯誤),不須要在程序中作任何處理,出現問題後,應該在程序在外的地方找問題,而後解決。

  6、異常轉型和異常鏈

  異常轉型在上面已經提到過了,實際上就是捕獲到異常後,將異常以新的類型的異常再拋出,這樣作通常爲了異常的信息更直觀!好比:

 

 public void run() throws MyException{
  ...
  try{
  ...
  }catch(IOException e){
  ...
  throw new MyException();
  }finally{
  ...
  }
  }

  異常鏈,在JDK1.4之後版本中,Throwable類支持異常鏈機制。Throwable 包含了其線程建立時線程執行堆棧的快照。它還包含了給出有關錯誤更多信息的消息字符串。最後,它還能夠包含 cause(緣由):另外一個致使此 throwable 拋出的 throwable。它也稱爲異常鏈 設施,由於 cause 自身也會有 cause,依此類推,就造成了異常鏈,每一個異常都是由另外一個異常引發的。

 

  通俗的說,異常鏈就是把原始的異常包裝爲新的異常類,並在新的異常類中封裝了原始異常類,這樣作的目的在於找到異常的根本緣由。

  經過Throwable的兩個構造方法能夠建立自定義的包含異常緣由的異常類型:

  Throwable(String message, Throwable cause)

  構造一個帶指定詳細消息和 cause 的新 throwable。

  Throwable(Throwable cause)

  構造一個帶指定 cause 和 (cause==null ? null :cause.toString())(它一般包含類和 cause 的詳細消息)的詳細消息的新 throwable。

  getCause()

  返回此 throwable 的 cause;若是 cause 不存在或未知,則返回 null。

  initCause(Throwable cause)

  將此 throwable 的 cause 初始化爲指定值。

  在Throwable的子類Exception中,也有相似的指定異常緣由的構造方法:

  Exception(String message, Throwable cause)

  構造帶指定詳細消息和緣由的新異常。

  Exception(Throwable cause)

  根據指定的緣由和 (cause==null ? null : cause.toString()) 的詳細消息構造新異常(它一般包含 cause 的類和詳細消息)。

  所以,能夠經過擴展Exception類來構造帶有異常緣由的新的異常類。

  7、Java異常處理的原則和技巧

  一、避免過大的try塊,不要把不會出現異常的代碼放到try塊裏面,儘可能保持一個try塊對應一個或多個異常。

  二、細化異常的類型,不要無論什麼類型的異常都寫成Excetpion。

  三、catch塊儘可能保持一個塊捕獲一類異常,不要忽略捕獲的異常,捕獲到後要麼處理,要麼轉譯,要麼從新拋出新類型的異常。

  四、不要把本身能處理的異常拋給別人。

  五、不要用try...catch參與控制程序流程,異常控制的根本目的是處理程序的非正常狀況。

      8、常見的幾種異常及可能的致使緣由:

 

       算術異常類:ArithmeticExecption

  空指針異常類:NullPointerException

  類型強制轉換異常:ClassCastException

  數組負下標異常:NegativeArrayException

  數組下標越界異常:ArrayIndexOutOfBoundsException

  違背安全原則異常:SecturityException

  文件已結束異常:EOFException

  文件未找到異常:FileNotFoundException

  字符串轉換爲數字異常:NumberFormatException

  操做數據庫異常:SQLException

  輸入輸出異常:IOException

  方法未找到異常:NoSuchMethodException

  java.lang.AbstractMethodError

  抽象方法錯誤。當應用試圖調用抽象方法時拋出。

  java.lang.AssertionError

  斷言錯。用來指示一個斷言失敗的狀況。

  java.lang.ClassCircularityError

  類循環依賴錯誤。在初始化一個類時,若檢測到類之間循環依賴則拋出該異常。

  java.lang.ClassFormatError

  類格式錯誤。當Java虛擬機試圖從一個文件中讀取Java類,而檢測到該文件的內容不符合類的有效格式時拋出。

  java.lang.Error

  錯誤。是全部錯誤的基類,用於標識嚴重的程序運行問題。這些問題一般描述一些不該被應用程序捕獲的反常狀況。

  java.lang.ExceptionInInitializerError

  初始化程序錯誤。當執行一個類的靜態初始化程序的過程當中,發生了異常時拋出。靜態初始化程序是指直接包含於類中的static語句段。

  java.lang.IllegalAccessError

  違法訪問錯誤。當一個應用試圖訪問、修改某個類的域(Field)或者調用其方法,可是又違反域或方法的可見性聲明,則拋出該異常。

  java.lang.IncompatibleClassChangeError

  不兼容的類變化錯誤。當正在執行的方法所依賴的類定義發生了不兼容的改變時,拋出該異常。通常在修改了應用中的某些類的聲明定義而沒有對整個應用從新編譯而直接運行的狀況下,容易引起該錯誤。

  java.lang.InstantiationError

  實例化錯誤。當一個應用試圖經過Java 的new操做符構造一個抽象類或者接口時拋出該異常.

  java.lang.InternalError

  內部錯誤。用於指示Java虛擬機發生了內部錯誤。

  java.lang.LinkageError

  連接錯誤。該錯誤及其全部子類指示某個類依賴於另一些類,在該類編譯以後,被依賴的類改變了其類定義而沒有從新編譯全部的類,進而引起錯誤的狀況。

  java.lang.NoClassDefFoundError

  未找到類定義錯誤。當Java虛擬機或者類裝載器試圖實例化某個類,而找不到該類的定義時拋出該錯誤。

  java.lang.NoSuchFieldError

  域不存在錯誤。當應用試圖訪問或者修改某類的某個域,而該類的定義中沒有該域的定義時拋出該錯誤。

  java.lang.NoSuchMethodError

  方法不存在錯誤。當應用試圖調用某類的某個方法,而該類的定義中沒有該方法的定義時拋出該錯誤。

  java.lang.OutOfMemoryError

  內存不足錯誤。當可用內存不足以讓Java虛擬機分配給一個對象時拋出該錯誤。

  java.lang.StackOverflowError

  堆棧溢出錯誤。當一個應用遞歸調用的層次太深而致使堆棧溢出時拋出該錯誤。

  java.lang.ThreadDeath

  線程結束。當調用 Thread類的stop方法時拋出該錯誤,用於指示線程結束。

  java.lang.UnknownError

  未知錯誤。用於指示 Java虛擬機發生了未知嚴重錯誤的狀況。

  java.lang.UnsatisfiedLinkError

  未知足的連接錯誤。當Java 虛擬機未找到某個類的聲明爲native方法的本機語言定義時拋出。

  java.lang.UnsupportedClassVersionError

  不支持的類版本錯誤。當Java虛擬機試圖從讀取某個類文件,可是發現該文件的主、次版本號不被當前Java虛擬機支持的時候,拋出該錯誤。

  java.lang.VerifyError

  驗證錯誤。當驗證器檢測到某個類文件中存在內部不兼容或者安全問題時拋出該錯誤。

  java.lang.VirtualMachineError

  虛擬機錯誤。用於指示虛擬機被破壞或者繼續執行操做所需的資源不足的狀況。

  java.lang.ArithmeticException

  算術條件異常。譬如:整數除零等。

  java.lang.ArrayIndexOutOfBoundsException

  數組索引越界異常。當對數組的索引值爲負數或大於等於數組大小時拋出。

  java.lang.ArrayStoreException

  數組存儲異常。當向數組中存放非數組聲明類型對象時拋出。

  java.lang.ClassCastException

  類造型異常。假設有類A和B(A不是B的父類或子類),O是A的實例,那麼當強制將O構造爲類B的實例時拋出該異常。該異常常常被稱爲強制類型轉換異常。

  java.lang.ClassNotFoundException

  找不到類異常。當應用試圖根據字符串形式的類名構造類,而在遍歷CLASSPAH以後找不到對應名稱的class文件時,拋出該異常。

  java.lang.CloneNotSupportedException

  不支持克隆異常。當沒有實現Cloneable接口或者不支持克隆方法時,調用其clone()方法則拋出該異常。

  java.lang.EnumConstantNotPresentException

  枚舉常量不存在異常。當應用試圖經過名稱和枚舉類型訪問一個枚舉對象,但該枚舉對象並不包含常量時,拋出該異常。

  java.lang.Exception

  根異常。用以描述應用程序但願捕獲的狀況。

  java.lang.IllegalAccessException

  違法的訪問異常。當應用試圖經過反射方式建立某個類的實例、訪問該類屬性、調用該類方法,而當時又沒法訪問類的、屬性的、方法的或構造方法的定義時拋出該異常。

  java.lang.IllegalMonitorStateException

  違法的監控狀態異常。當某個線程試圖等待一個本身並不擁有的對象(O)的監控器或者通知其餘線程等待該對象(O)的監控器時,拋出該異常。

  java.lang.IllegalStateException

  違法的狀態異常。當在Java環境和應用還沒有處於某個方法的合法調用狀態,而調用了該方法時,拋出該異常。

  java.lang.IllegalThreadStateException

  違法的線程狀態異常。當縣城還沒有處於某個方法的合法調用狀態,而調用了該方法時,拋出異常。

  java.lang.IndexOutOfBoundsException

  索引越界異常。當訪問某個序列的索引值小於0或大於等於序列大小時,拋出該異常。

  java.lang.InstantiationException

  實例化異常。當試圖經過newInstance()方法建立某個類的實例,而該類是一個抽象類或接口時,拋出該異常。

  java.lang.InterruptedException

  被停止異常。當某個線程處於長時間的等待、休眠或其餘暫停狀態,而此時其餘的線程經過Thread的interrupt方法終止該線程時拋出該異常。

  java.lang.NegativeArraySizeException

  數組大小爲負值異常。當使用負數大小值建立數組時拋出該異常。

  java.lang.NoSuchFieldException

  屬性不存在異常。當訪問某個類的不存在的屬性時拋出該異常。

  java.lang.NoSuchMethodException

  方法不存在異常。當訪問某個類的不存在的方法時拋出該異常。

  java.lang.NullPointerException

  空指針異常。當應用試圖在要求使用對象的地方使用了null時,拋出該異常。譬如:調用null對象的實例方法、訪問null對象的屬性、計算null對象的長度、使用throw語句拋出 null等等。

  java.lang.NumberFormatException

  數字格式異常。當試圖將一個String轉換爲指定的數字類型,而該字符串確不知足數字類型要求的格式時,拋出該異常。

  java.lang.RuntimeException

  運行時異常。是全部Java虛擬機正常操做期間能夠被拋出的異常的父類。

  java.lang.SecurityException

  安全異常。由安全管理器拋出,用於指示違反安全狀況的異常。

  java.lang.StringIndexOutOfBoundsException

  字符串索引越界異常。當使用索引值訪問某個字符串中的字符,而該索引值小於0或大於等於序列大小時,拋出該異常。

  java.lang.TypeNotPresentException

  類型不存在異常。當應用試圖以某個類型名稱的字符串表達方式訪問該類型,可是根據給定的名稱又找不到該類型是拋出該異常。該異常與 ClassNotFoundException的區別在於該異常是unchecked(不被檢查)異常,而ClassNotFoundException 是checked(被檢查)異常。

  java.lang.UnsupportedOperationException

  不支持的方法異常。指明請求的方法不被支持狀況的異常。

     異常

  javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login (/Login是你的action名字)

  可能緣由

  action 沒有再struts-config.xml 中定義,或沒有找到匹配的action,例如在JSP文件中使用 後面使用 Struts的html標記。另外要注意可能你不經意使用的無主體的標記,如 ,這樣web 服務器解析時就看成一個無主體的標記,隨後使用的全部標記都被認爲是在這個標記以外的,如又使用了 還有就是在使用taglib引入HTML標記庫時,你使用的prefix的值不是html。

  -----------------------------------------------------------------------------------------------------------------

  異常

  org.apache.jasper.JasperException: Cannot retrieve definition for form bean null

  可能緣由

  這個異常是由於Struts根據struts- config.xml中的mapping沒有找到action指望的form bean。大部分的狀況多是由於在form-bean中設置的name屬性和action中設置的name屬性不匹配所致。換句話說,action和 form都應該各自有一個name屬性,而且要精確匹配,包括大小寫。這個錯誤當沒有name屬性和action關聯時也會發生,若是沒有在action 中指定name屬性,那麼就沒有name屬性和action相關聯。固然當action製做某些控制時,譬如根據參數值跳轉到相應的jsp頁面,而不是處理表單數據,這是就不用name屬性,這也是action的使用方法之一。

  -----------------------------------------------------------------------------------------------------------------

  異常

  No action instance for path /xxxx could be created

  可能緣由

  特別提示:由於有不少中狀況會致使這個錯誤的發生,因此推薦你們調高你的web服務器的日誌/調試級別,這樣能夠從更多的信息中看到潛在的、在試圖建立action 類時發生的錯誤,這個action類你已經在struts-config.xml中設置了關聯(即添加了標籤)。

  在 struts-config.xml中經過action標籤的class屬性指定的action類不能被找到有不少種緣由,例如:定位編譯後的.class文件失敗。Failure to place compiled .class file for the action in the classpath (在web開發中,class的的位置在r WEB-INF/classes,因此你的action class必需要在這個目錄下。例如你的action類位於WEB-INF/classes/action/Login.class,那麼在 struts-config.xml中設置action的屬性type時就是action.Login).

  拼寫錯誤,這個也時有發生,而且不易找到,特別注意第一個字母的大小寫和包的名稱。

  -----------------------------------------------------------------------------------------------------------------

  異常

  javax.servlet.jsp.JspException: No getter method for property username of bean org.apache.struts.taglib.html.BEAN

  可能緣由

  沒有位form bean中的某個變量定義getter 方法

  這個錯誤主要發生在表單提交的FormBean中,用struts標記 時,在FormBean中必須有一個getUsername()方法。注意字母「U」。

  -----------------------------------------------------------------------------------------------------------------

  異常

  java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm

  可能緣由

  這個錯誤主要發生在在classpath中找不到相應的Java .class文件。若是這個錯誤發生在web應用程序的運行時,主要是由於指定的class文件不在web server的classpath中(/WEB-INF/classes 和 /WEB-INF/lib)。在上面的錯誤中,緣由是找不到ActionForm類。

  -----------------------------------------------------------------------------------------------------------------

  異常

  javax.servlet.jsp.JspException: Exception creating bean of class org.apache.struts.action.ActionForm: {1}

  可能緣由

  Instantiating Struts-provided ActionForm class directly instead of instantiating a class derived off ActionForm. This mightoccur implicitly if you specify that a form-bean is this Struts ActionForm class rather than specifying a child of this classfor the form-bean.

  Not associating an ActionForm-descended class with an action can also lead to this error.

  -----------------------------------------------------------------------------------------------------------------

  異常

  javax.servlet.jsp.JspException: Cannot find ActionMappings or ActionFormBeans collection

  可能緣由

  不是標識Struts actionServlet的標記就是映射.do擴展名的標記或者二者都沒有在web.xml中聲明。

  在struts-config.xml中的打字或者拼寫錯誤也可致使這個異常的發生。例如缺乏一個標記的關閉符號 />。最好使用struts console工具檢查一下。

  另外,load-on-startup必須在web.xml中聲明,這要麼是一個空標記,要麼指定一個數值,這個數值用來表servlet運行的優先級,數值越大優先級越低。

  還有一個和使用load-on-startup有關的是使用Struts預編譯JSP文件時也可能致使這個異常。

  -----------------------------------------------------------------------------------------------------------------

  異常

  java.lang.NullPointerException at org.apache.struts.util.RequestUtils.forwardURL(RequestUtils.java:1223)

  可能緣由

  在struts-config.xml中的forward元素缺乏path屬性。例如應該是以下形式:

  

  -----------------------------------------------------------------------------------------------------------------

  異常

  javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope

  Probable Causes

  試圖在Struts的form標記外使用form的子元素。這經常發生在你在

  -----------------------------------------------------------------------------------------------------------------

  異常

  javax.servlet.jsp.JspException: Missing message for key xx.xx.xx

  Probable Causes

  這個key的值對沒有在資源文件ApplicationResources.properties中定義。若是你使用 eclipse時常常碰到這樣的狀況,當項目從新編譯時,eclipse會自動將classes目錄下的資源文件刪除。

  資源文件 ApplicationResources.properties 不在classpath中應將資源文件放到 WEB-INF/classes 目錄下,固然要在struts-config.xml中定義)

  -----------------------------------------------------------------------------------------------------------------

  異常

  Cannot find message resources under key org.apache.struts.action.MESSAGE

  可能緣由

  很顯然,這個錯誤是發生在使用資源文件時,而Struts沒有找到資源文件。

  Implicitly trying to use message resources that are not available (such as using empty html:options tag instead of specifyingthe options in its body -- this assumes options are specified in ApplicationResources.properties file)

  XML parser issues -- too many, too few, incorrect/incompatible versions

  -----------------------------------------------------------------------------------------------------------------

  異常

  Strange and seemingly random characters in HTML and on screen, but not in original JSP or servlet.

  可能緣由

  混和使用Struts的html:form標記和標準的 HTML標記不正確。

  使用的編碼樣式在本頁中不支持。

  -----------------------------------------------------------------------------------------------------------------

  異常

  "Document contained no data" in Netscape

  No data rendered (completely empty) page in Microsoft Internet Explorer

  可能緣由

  使用一個 Action的派生類而沒有實現perform()方法或execute()方法。在Struts1.0中實現的是perform()方法,在 Struts1.1中實現的是execute()方法,但Struts1.1向後兼容perform()方法。但你使用Struts1.1建立一個 Action的派生類,而且實現了execute()方法,而你在Struts1.0中運行的話,就會獲得"Document contained nodata" error message in Netscape or a completely empty (no HTML whatsoever) page rendered in Microsoft Internet Explorer.」的錯誤信息。

  ---------------------------------------------------------------------------------------------------------------------------

  異常

  ServletException: BeanUtils.populate

  解決方案

  在用Struts上傳文件時,遇到了 javax.servlet.ServletException: BeanUtils.populate異常。

  個人ActionServlet 並無用到BeanUtils這些工具類。後來仔細檢查代碼發現是在jsp文件裏的form忘了加enctype=" multipart/form-data" 了。因此寫程序遇到錯誤或異常應該從多方面考慮問題存在的可能性,想到系統提示信息之外的東西。

  ----------------------------------------------------------------------------------------------------------------------------

  1. 定義Action後, 若是指定了name, 那麼必需要定義一個與它同名的FormBean才能進行form映射.2. 若是定義Action後, 提交頁面時出現 "No input attribute for mapping path..." 錯誤, 則須要在其input屬性中定義轉向的頁面.3. 若是插入新的數據時出現 "Batch update row count wrong:..." 錯誤, 則說明XXX.hbm.xml中指定的key的類型爲原始類型(int, long),由於這種類型會自動分配值, 而這個值每每會讓系統認爲已經存在該記錄, 正確的方法是使用java.lang.Integer或java.lang.Long對象.4. 若是插入數據時出現 "argument type mismatch" 錯誤, 多是你使用了Date等特殊對象, 由於struts不能自動從String型轉換成Date型,因此, 你須要在Action中手動把String型轉換成Date型.5. Hibernate中, Query的iterator()比list()方法快不少.6. 若是出現 "equal symbol expected" 錯誤, 說明你的strtus標籤中包含另外一個標籤或者變量, 例如:

 <html:select property="test" onchange="<%=test%>"/>

或者<html:hidden property="test" value="<bean:write name="t" property="p"/>"/>這樣的狀況...

相關文章
相關標籤/搜索