<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-204  評論-149  文章-0  trackbacks-0
    RuntimeException異常以及其子類異常,不需要異常說明就可以從任何地方拋出
    是uncheck exception。

    從程序的輸出看出,無論有沒有拋出異常,finally子句總會得到執行,
    這個程序也啟發我們應該如何處理我們前面講到過的,Java異常(和C
    ++
    的異常一樣)會阻止程序回到異常拋出的地方恢復執行這個問題。
    如果你把try塊放進一個循環,你就能構建一個程序運行之前必須滿足的條件。

    class ThreeException extends Exception{
        
    }

    public class FinallyWorks {

        
        
    static int count = 0;
        
        
    public static void main(String[] args) {
            
    while(true){
                
    try{
                    
    if(count++==0){
                        
    throw new ThreeException();
                    }

                    System.out.println(
    "No Exception");
                }
    catch(Exception e){
                    System.err.println(
    "ThreeException");
                }
    finally{
                    System.err.println(
    "In finally clause");
                    
    if(count==2)
                        
    break;
                }

            }

        }


    }


    ThreeException
    In 
    finally clause
    No Exception
    In 
    finally clause





    Finally子句的執行
    class FourException extends Exception {
    }


    public class AlwaysFinally {

        
    public static void main(String[] args){
            System.out.println(
    "Entering first try block");
            
    try {
                System.out.println(
    "Entering second try block");
                
    try {
                    
    throw new FourException();
                }
     finally {
                    System.out.println(
    "finally in 2nd try block");
                }

            }
     catch (FourException e) {
                System.err.println(
    "Caught FourException in 1st try block");
            }
     finally {
                System.err.println(
    "finally in 1st try block");
            }


        }

    }

    Entering first 
    try block
    Entering second 
    try block
    finally in 2nd try block
    Caught FourException in 1st 
    try block
    finally in 1st try block





    丟失的異常
    package exceptiontest;

    class VeryImportantException extends Exception {
        
    public String toString() {
            
    return "A very important exception!";
        }

    }


    class HoHumException extends Exception {
        
    public String toString() {
            
    return "A trivial exception";
        }

    }


    public class LostMessage {
        
    void f() throws VeryImportantException {
            
    throw new VeryImportantException();
        }


        
    void dispose() throws HoHumException {
            
    throw new HoHumException();
        }


        
    public static void main(String[] args) throws Exception {
            LostMessage lm 
    = new LostMessage();
            
    try {
                lm.f();
            }
     finally {
                lm.dispose();
            }


        }

    }


    看到了嗎?VeryImportantException消失的無影無蹤了,它直接被finally里面的HoHumException給取代了,這是一個相當嚴重的錯誤,它表示這個異常被徹底丟失了,而在真實環境中,這種情況會遠比上述程序更為微妙,更難以察覺。相反,C
    ++會把這種“第一個異常尚未得到處理,就產生了第二個異常”的現象,當成極端嚴重的編程錯誤。







    //Java構造函數中發生的異常
    class InputFile {
        
    private BufferedReader in;

        
    public InputFile(String fname) throws Exception {
            
    try {
                in 
    = new BufferedReader(new FileReader(fname));
                
    // Other code that might throw exceptions
            }
     catch (FileNotFoundException e) {
                System.err.println(
    "Could not open " + fname);
                
    // Wasn't open, so don't close it
                throw e;
            }
     catch (Exception e) {
                
    // All other exceptions must close it
                try {
                    in.close();
                }
     catch (IOException e2) {
                    System.err.println(
    "in.close() unsuccessful");
                }

                
    throw e; // Rethrow
            }
     finally {
                
    // Don't close it here!!!
            }

        }


        
    public String getLine() {
            String s;
            
    try {
                s 
    = in.readLine();
            }
     catch (IOException e) {
                
    throw new RuntimeException("readLine() failed");
            }

            
    return s;
        }


        
    public void dispose() {
            
    try {
                in.close();
                System.out.println(
    "dispose() successful");
            }
     catch (IOException e2) {
                
    throw new RuntimeException("in.close() failed");
            }

        }

    }


    public class Cleanup {
        
    private static Test monitor = new Test();

        
    public static void main(String[] args) {
            
    try {
                InputFile in 
    = new InputFile("Cleanup.java");
                String s;
                
    int i = 1;
                
    while ((s = in.getLine()) != null)
                    ; 
    // Perform line-by-line processing here
                in.dispose();
            }
     catch (Exception e) {
                System.err.println(
    "Caught Exception in main");
                e.printStackTrace();
            }

            monitor.expect(
    new String[] "dispose() successful" });
        }

    }
     // /:~



    異常處理系統還是一扇能讓你放棄程序正常運行順序的暗門。當某種“異常情況”出現的時候,這個門就開啟了,于是程序再也不能,或者再也不按照正常的順序執行下去。異常表示的是一些“當前方法無法處理”的情況。之所以要開發異常處理系統,是因為要對每次函數調用的每個錯誤做檢查實在是太費力了,所以程序員根本就不去做。結果就是把錯誤給忽略了。
    異常處理的一個重要準則就是“如果你不知道該如何處理這個異常,你就別去捕捉它”。實際上,異常處理有一項重要的目標,這就是將處理異常的代碼從異常發生的地方移開。這樣你就能在一個地方集中精力去解決你想解決的問題,然后再到另外一個地方處理這些異常問題了。
    但是 java所特有的checked exception將這種情況變的稍微復雜些了,這是因為即使你不準備這么做,編譯器也強制要求你在try的后面加上catch子句,于是這就導致了“錯誤地私吞harmful 
    if swallowed”的問題了:


    注意一下throw e.fillInStackTrace();的用法

    package exceptiontest;

    import java.util.Collections;

    public class Rethrowing {
        
    public static void f()throws Exception{
            System.err.println(
    "originating the exception n f()");
            
    throw new Exception("throw from f()");
        }

        
    public static void g()throws Throwable{
            
    try{
                f();
            }
    catch(Exception e){
                System.err.println(
    "Inside g(),e.printlStackTrace()");
                e.printStackTrace();
                
    //throw e;
                throw e.fillInStackTrace();
            }

            
        }

        
    public static void h()throws Exception{
            f();
        }

        
    public static void main(String[] args)throws Throwable{
            
    try{
                g();
            }
    catch(Exception e){
                System.err.println(
    "Caught in main,e.printStackTrace");
                e.printStackTrace();
            }

        }


    }

    運行結果:
    originating the exception n f()
    Inside g(),e.printlStackTrace()
    java.lang.Exception: throw from f()
     at exceptiontest.Rethrowing.f(Rethrowing.java:8)
     at exceptiontest.Rethrowing.g(Rethrowing.java:12)
     at exceptiontest.Rethrowing.main(Rethrowing.java:26)
    Caught in main,e.printStackTrace
    java.lang.Exception: throw from f()
     at exceptiontest.Rethrowing.g(Rethrowing.java:17)
     at exceptiontest.Rethrowing.main(Rethrowing.java:26)


    如不使用 throw e.fillInStackTrace(),而是throw e
    originating the exception n f()
    Inside g(),e.printlStackTrace()
    java.lang.Exception: throw from f()
     at exceptiontest.Rethrowing.f(Rethrowing.java:8)
     at exceptiontest.Rethrowing.g(Rethrowing.java:12)
     at exceptiontest.Rethrowing.main(Rethrowing.java:26)
    Caught in main,e.printStackTrace
    java.lang.Exception: throw from f()
     at exceptiontest.Rethrowing.f(Rethrowing.java:8)
     at exceptiontest.Rethrowing.g(Rethrowing.java:12)
     at exceptiontest.Rethrowing.main(Rethrowing.java:26)



    Exception chaining

    Often you want to catch one exception and throw another, but still keep the information about the originating exception—this is called exception chaining. Prior to JDK 1.4, programmers had to write their own code to preserve the original exception information, but now all Throwable subclasses may take a cause object in their constructor. The cause is intended to be the originating exception, and by passing it in you maintain the stack trace back to its origin, even though you’re creating and throwing a new exception at this point.

    It’s interesting to note that the only Throwable subclasses that provide the cause argument in the constructor are the three fundamental exception classes Error (used by the JVM to report system errors), Exception, and RuntimeException. If you want to chain any other exception types, you do it through the initCause( ) method rather than the constructor.

    //: c09:DynamicFields.java
    // A Class that dynamically adds fields to itself.
    // Demonstrates exception chaining.
    // {ThrowsException}
    import com.bruceeckel.simpletest.*;

    class DynamicFieldsException extends Exception {}

    public class DynamicFields {
      
    private static Test monitor = new Test();
      
    private Object[][] fields;
      
    public DynamicFields(int initialSize) {
        fields 
    = new Object[initialSize][2];
        
    for(int i = 0; i < initialSize; i++)
          fields[i] 
    = new Object[] nullnull };
      }

      
    public String toString() {
        StringBuffer result 
    = new StringBuffer();
        
    for(int i = 0; i < fields.length; i++{
          result.append(fields[i][
    0]);
          result.append(
    "");
          result.append(fields[i][
    1]);
          result.append(
    "\n");
        }

        
    return result.toString();
      }

      
    private int hasField(String id) {
        
    for(int i = 0; i < fields.length; i++)
          
    if(id.equals(fields[i][0]))
            
    return i;
        
    return -1;
      }

      
    private int
      getFieldNumber(String id) 
    throws NoSuchFieldException {
        
    int fieldNum = hasField(id);
        
    if(fieldNum == -1)
          
    throw new NoSuchFieldException();
        
    return fieldNum;
      }

      
    private int makeField(String id) {
        
    for(int i = 0; i < fields.length; i++)
          
    if(fields[i][0== null{
            fields[i][
    0= id;
            
    return i;
          }

        
    // No empty fields. Add one:
        Object[][]tmp = new Object[fields.length + 1][2];
        
    for(int i = 0; i < fields.length; i++)
          tmp[i] 
    = fields[i];
        
    for(int i = fields.length; i < tmp.length; i++)
          tmp[i] 
    = new Object[] nullnull };
        fields 
    = tmp;
        
    // Reursive call with expanded fields:
        return makeField(id);
      }

      
    public Object
      getField(String id) 
    throws NoSuchFieldException {
        
    return fields[getFieldNumber(id)][1];
      }

      
    public Object setField(String id, Object value)
      
    throws DynamicFieldsException {
        
    if(value == null{
          
    // Most exceptions don't have a "cause" constructor.
          
    // In these cases you must use initCause(),
          
    // available in all Throwable subclasses.
          DynamicFieldsException dfe =
            
    new DynamicFieldsException();
          dfe.initCause(
    new
     NullPointerException());
          
    throw
     dfe;
        }

        
    int fieldNumber = hasField(id);
        
    if(fieldNumber == -1)
          fieldNumber 
    = makeField(id);
        Object result 
    = null;
        
    try {
          result 
    = getField(id); // Get old value
        }
     catch(NoSuchFieldException e) {
          
    // Use constructor that takes "cause":
          throw new RuntimeException(e);
        }

        fields[fieldNumber][
    1= value;
        
    return result;
      }

      
    public static void main(String[] args) {
        DynamicFields df 
    = new DynamicFields(3);
        System.out.println(df);
        
    try {
          df.setField(
    "d""A value for d");
          df.setField(
    "number"new Integer(47));
          df.setField(
    "number2"new Integer(48));
          System.out.println(df);
          df.setField(
    "d""A new value for d");
          df.setField(
    "number3"new Integer(11));
          System.out.println(df);
          System.out.println(df.getField(
    "d"));
          Object field 
    = df.getField("a3"); // Exception
        }
     catch(NoSuchFieldException e) {
          
    throw new RuntimeException(e);
        }
     catch(DynamicFieldsException e) {
          
    throw new RuntimeException(e);
        }

        monitor.expect(
    new String[] {
          
    "null: null",
          
    "null: null",
          
    "null: null",
          
    "",
          
    "d: A value for d",
          
    "number: 47",
          
    "number2: 48",
          
    "",
          
    "d: A new value for d",
          
    "number: 47",
          
    "number2: 48",
          
    "number3: 11",
          
    "",
          
    "A value for d",
          
    "Exception in thread \"main\" " +
          
    "java.lang.RuntimeException: " +
          
    "java.lang.NoSuchFieldException",
          
    "\tat DynamicFields.main(DynamicFields.java:98)",
          
    "Caused by: java.lang.NoSuchFieldException",
          
    "\tat DynamicFields.getFieldNumber(" +
          
    "DynamicFields.java:37)",
          
    "\tat DynamicFields.getField(DynamicFields.java:58)",
          
    "\tat DynamicFields.main(DynamicFields.java:96)"
        }
    );
      }

    }
     ///:~




    方法覆蓋時異常的情況
    package exceptiontest;
    //方法覆蓋時異常的情況
    //: c09:StormyInning.java
    //Overridden methods may throw only the exceptions
    //specified in their base-class versions, or exceptions
    //derived from the base-class exceptions.

    class BaseballException extends Exception {
    }


    class Foul extends BaseballException {
    }


    class Strike extends BaseballException {
    }


    abstract class Inning {
        
    public Inning() throws BaseballException {
        }


        
    public void event() throws BaseballException {
            
    // Doesn't actually have to throw anything
        }


        
    public abstract void atBat() throws Strike, Foul;

        
    public void walk() {
        }
     // Throws no checked exceptions
    }


    class StormException extends Exception {
    }


    class RainedOut extends StormException {
    }


    class PopFoul extends Foul {
    }


    interface Storm {
        
    public void event() throws RainedOut;

        
    public void rainHard() throws RainedOut;
    }


    public class StormyInning extends Inning implements Storm {
        
    // OK to add new exceptions for constructors, but you
        
    // must deal with the base constructor exceptions:
        
    //構造函數可以多,但是它必須加基類構造函數所聲明的異常
        public StormyInning() throws RainedOut, BaseballException {
        }


        
    public StormyInning(String s) throws Foul, BaseballException {
        }


        
    // Regular methods must conform to base class:
        
    //異常聲明只少不多,但這種異常方面的限制對構造函數不起作用
        
    // ! void walk() throws PopFoul {} //Compile error
        
    // Interface CANNOT add exceptions to existing
        
    // methods from the base class:以基類為準而不是以接口為準
        
    // ! public void event() throws RainedOut {}
        
    // If the method doesn't already exist in the
        
    // base class, the exception is OK:
        public void rainHard() throws RainedOut {
        }


        
    // You can choose to not throw any exceptions,
        
    // even if the base version does:
        
    //異常聲明只少不多*****************************
        public void event() {
        }


        
    // Overridden methods can throw inherited exceptions:
        public void atBat() throws PopFoul {
        }


        
    public static void main(String[] args) {
            
    try {
                StormyInning si 
    = new StormyInning();
                si.atBat();
            }
     catch (PopFoul e) {
                System.err.println(
    "Pop foul");
            }
    catch(Foul e){
                
            }
    catch (RainedOut e) {
                System.err.println(
    "Rained out");
            }
     catch (BaseballException e) {
                System.err.println(
    "Generic baseball exception");
            }

            
    // Strike not thrown in derived version.
            try {
                
    // What happens if you upcast?
                Inning i = new StormyInning();
                i.atBat();
                
    // You must catch the exceptions from the
                
    // base-class version of the method:
            }
     catch (Strike e) {
                System.err.println(
    "Strike");
            }
     catch (Foul e) {
                System.err.println(
    "Foul");
            }
     catch (RainedOut e) {
                System.err.println(
    "Rained out");
            }
     catch (BaseballException e) {
                System.err.println(
    "Generic baseball exception");
            }

        }

    }

    posted on 2009-06-18 23:40 Frank_Fang 閱讀(1007) 評論(0)  編輯  收藏 所屬分類: Java編程
    主站蜘蛛池模板: 亚洲精品无码鲁网中文电影| 亚洲精品美女视频| 亚洲精品无码MV在线观看| 无遮挡a级毛片免费看| 久久国产精品成人片免费| 亚洲成A人片77777国产| 亚洲电影在线免费观看| 91精品免费高清在线| 亚洲精品欧洲精品| 最近免费中文字幕4| 久久精品国产精品亚洲蜜月| 免费国产高清毛不卡片基地| 亚洲国产成人五月综合网 | 男人免费视频一区二区在线观看 | 日韩免费视频播播| 亚洲成年人电影在线观看| 中文字幕高清免费不卡视频| 波多野结衣一区二区免费视频| 亚洲国产精品成人精品小说| 无码区日韩特区永久免费系列| 在线观看亚洲人成网站| 成全高清在线观看免费| 亚洲国产精品尤物yw在线| 永久免费AV无码网站国产 | 波多野结衣免费视频观看| 亚洲视频在线免费| 亚洲av日韩av欧v在线天堂| 亚洲精品亚洲人成在线| 成年女人男人免费视频播放| 久久亚洲精品无码av| 成人免费毛片视频| eeuss影院ss奇兵免费com| 亚洲欧洲尹人香蕉综合| 妞干网免费观看视频| 亚洲人成77777在线观看网| 免费国产成人高清在线观看网站| 国产成人精品久久亚洲高清不卡| 全免费a级毛片免费看不卡| 亚洲色一区二区三区四区| 午夜毛片不卡高清免费| 一级人做人爰a全过程免费视频|