国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

突破Java異常處理規則

2019-11-18 15:43:20
字體:
來源:轉載
供稿:網友

  Q: 我在我的應用程序中調用了外部方法并且想捕捉它可能拋出的異常。我能捕捉java.lang.Exception嗎?

  A: 通過一個給定的方法去處理所有運行時和檢測異常對于預防外部錯誤是不充分的。

  你可以去讀目前 JavaWorld文章 – “Java Tip 134: When Catching Exception, Don’t Cast Your Net Too Wide”。這篇文章警告了捕捉java.lang.Exception和java.lang.Throable是不好的。捕捉你能指定的異常對于代碼的可維護性是十分重要的。然而這個規則依靠于非凡的環境。假如你不打算你的程序崩潰并且保留你的數據結構的安全異常,那么你必須捕捉被拋出的真正的異常。


  舉個例子,想象你有一個加載了這個接口的服務器應用:

public interface IFoo
{
 /**
 * This method can't throw any checked exceptions...or can it?
 */
 void bar ();
} // End of interface
  對于給出參數的理由是讓我們通知你這樣的服務在什么地方,并且不同的IFoo實現能夠從外部資源加載上。你寫如下代碼:

try
{
 IFoo foo = ... // get an IFoo implementation
 foo.bar ();
}
catch (RuntimeException ioe)
{
 // Handle 'ioe' ...
}
catch (Error e)
{
 // Handle or re-throw 'e' ...
}
  并且你在這個里處理了所有可能的異常。你不需要在這里加上任何捕捉java.io.IOException的異常,因為IFoo實現沒有從IFoo.bar()中拋出它,對嗎?(事實上,假如你加上了捕捉java.io.IOException異常塊,編譯器可能會把它作為不可到達的異常而丟棄)

  錯誤。在我寫的EvilFoo類中bar()方法證實了將拋出你傳遞給類構造器的任何異常:

public void bar ()
{
 EvilThrow.throwThrowable (m_throwthis);
}
  運行Main方法:

public class Main
{
 public static void main (final String[] args)
 {
  // This try/catch block appears to intercept all exceptions that
  // IFoo.bar() can throw; however, this is not true
  try
  {
   IFoo foo = new EvilFoo (new java.io.IOException ("SUR   foo.bar ();
  }
  catch (RuntimeException ioe)
  {
   // Ignore ioe
  }
  catch (Error e)
  {
   // Ignore e
  }
 }
} // End of class
  你將看到從bar()方法拋出的java.io.IOException異常實例并且沒有任何捕捉塊:

>java -cp classes Main
Exception in thread "main" java.io.IOException: SURPRISE!
at Main.main(Main.java:23)
  在這里發生了什么?

  主要的觀察是通常針對檢測異常的Java規則僅僅在編譯的時候被執行。在運行的時候,一個JVM不能保證被一個方法拋出的異常是否和在這個方法中聲明的拋出異常相匹配。因為調用方法的職責是捕捉和處理所有從調用方法拋出的異常。任何沒有被調用方法聲明的異常將不予理睬并且拒絕調用棧。

  假如正常行為是編譯器執行,那么我怎么創建EvilFoo的?至少有兩個方法可以去創建拋出沒有聲明的異常的Java方法:

   Thread.stop(Throwable)在一些時候不被贊成使用,但是它仍然被使用并且傳遞一個Throwable給被調用的Thread。

   分別編譯:你能在編譯EvilFoo時候不去編譯真正聲明bar()方法拋出檢測異常的IFoo臨時版本。

  我用后一種選擇:我編譯開始定義的EvilThrow類:

public abstract class EvilThrow
{
 public static void throwThrowable (Throwable throwable)
 throws Throwable
 {
  throw throwable;
 }
}
  接下來,我用Byte Code Engineering Library(BCEL)的JasminVisitor分解結果,在匯編代碼中刪除throwThrowable()方法Throwable的聲明,并且用Jasmin assembler 編譯新的版本。

  假如你編寫捕捉異常的構造器,那么它應該總是捕捉java.lang.Throwable而不僅僅只捕捉java.lang.Exception。這個規則適合你開發治理運行時的應用程序和必須執行可能包含錯誤甚至惡意代碼的外部
組件。你要確保捕捉Throwable并且過濾掉錯誤信息。

  下面示例說明了假如你沒有遵循這個建議將發生什么。

Example: Breaking SwingUtilities.invokeAndWait()

  javax.swing.SwingUtilities.invokeAndWait()是在AWT上執行一個線程的有用方法。當一個應用程序線程必須更新圖形用戶接口并且服從所有Swing線程規則的時候這個方法將被調用。一個沒有捕捉Runnable.run()拋出的異常將被捕捉并且被封裝在一個InvocationTragetException中重新拋出。

  Sun的J2SE1.4.1假設這樣一個未捕捉的異常僅僅是java.lang.Exception的子類。這里是一個SwingUtilities.invokeAndWait()調用java.awt.event.InvocationEvent的一個分析:



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兖州市| 长葛市| 克拉玛依市| 海兴县| 辽宁省| 乌恰县| 宽甸| 大竹县| 东明县| 墨脱县| 涟源市| 西盟| 辰溪县| 和林格尔县| 青龙| 仙桃市| 平湖市| 海盐县| 高邑县| 沙雅县| 临武县| 开封县| 永年县| 高唐县| 同江市| 岳普湖县| 安化县| 迭部县| 会昌县| 蕉岭县| 城固县| 定州市| 平泉县| 宜兰市| 临夏市| 贺州市| 尚志市| 镇康县| 北辰区| 五原县| 宁国市|