??xml version="1.0" encoding="utf-8" standalone="yes"?>久久香蕉频线观,国产女优一区,激情五月婷婷综合http://www.aygfsteel.com/coderdream/category/26299.html软g工程师成长之?/description>zh-cnFri, 22 Feb 2008 11:57:50 GMTFri, 22 Feb 2008 11:57:50 GMT60W??异常处理http://www.aygfsteel.com/coderdream/archive/2008/02/22/181382.htmlCoderDreamCoderDreamFri, 22 Feb 2008 09:50:00 GMThttp://www.aygfsteel.com/coderdream/archive/2008/02/22/181382.htmlhttp://www.aygfsteel.com/coderdream/comments/181382.htmlhttp://www.aygfsteel.com/coderdream/archive/2008/02/22/181382.html#Feedback0http://www.aygfsteel.com/coderdream/comments/commentRss/181382.htmlhttp://www.aygfsteel.com/coderdream/services/trackbacks/181382.html9.1 Java异常处理机制概述 主要考虑的两个问题:Q?Q如何表C异常情况?Q?Q如何控制处理异常的程Q?br />

9.1.1 Java异常处理机制的优?/h4> Java语言按照面向对象的思想来处理异常,使得E序h更好的可l护性?br />
Java异常处理机制h以下优点Q?br />
  • 把各U不同类型的异常情况q行分类Q用JavacL表示异常情况Q发挥类的可扩展性和可重用性?
  • 异常程的代码和正常程的代码分,提供了程序的可读性,化了E序的结构?
  • 可以灉|地处理异常,如果当前Ҏ有能力处理异常,捕获ƈ处理它,否则只需要抛出异常,由方法调用者来处理它?

9.1.2 Java虚拟机的Ҏ调用?/h4> 如果Ҏ中的代码块可能抛出异常,有如下两U处理方法:
Q?Q在当前Ҏ中通过try...catch语句捕获q处理异常;
Q?Q在Ҏ的声明处通过throws语句声明抛出异常?br /> 当Java虚拟溯到调用栈的底部的方法时Q如果仍然没有找到处理该异常的代码,按以下步骤处理Q?br /> Q?Q调用异常对象的printStachTrace()ҎQ打印来自方法调用栈的异怿息?br /> Q?Q如果该U程不是ȝE,那么l止q个U程Q其它线El正常运行。如果该U程是主U程Q那么整个应用程序被l止?br />

9.1.3 异常处理Ҏ能的媄?/h4> 一般来_影响很小Q除非方法嵌套调用很深?br />

9.2 q用Java异常处理机制

9.2.1 try...catch语句Q捕获异?/h4>

9.2.2 finally语句QQ何情况下都必L行的代码

主要用于关闭某些和数据库连接?

9.2.3 thorws子句Q声明可能会出现的异?/h4>

9.2.4 throw语句Q抛出异?/h4>

9.2.5 异常处理语句的语法规?/h4> Q?Qtry代码块不能脱catch代码块或finally代码块而单独存在。try代码块后面至有一个catch代码块或finally代码块?br /> Q?Qtry代码块后面可以有零个或多个catch代码块,q可以有零个或至多一个finally代码块?br /> Q?Qtry代码块后面可以只跟finally代码块?br /> Q?Q在try代码块中定义的变量的作用域ؓtry代码块,在catch代码块和finally代码块中不能讉K该变量?br /> Q?Q当try代码块后面有多个catch代码块时QJava虚拟Z把实际抛出的异常cd象依ơ和各个catch代码块声明的异常cd匚wQ如果异常对象ؓ某个异常cd或其子类的实例,执行这个catch代码块,而不会再执行其他的catch代码块?br /> Q?Q如果一个方法可能出现受查异常,要么用try...catch语句捕获Q要么用throws子句声明它抛出Q否则会D~译错误?br />

9.2.6 异常程的运行过E?/h4> Q?Qfinally语句不被执行的唯一情况是先执行了用于终止程序的System.exit()Ҏ?br /> Q?Qreturn语句用于退出本Ҏ?br /> Q?Qfinally代码块虽然在return语句之前被执行,但finally代码块不能通过重新l变量赋值来改变return语句的返回倹{?br /> Q?Q徏议不要在finally代码块中使用return语句Q因为它会导致以下两U潜在的错误
         AQ覆盖try或catch代码块的return语句
public class SpecialException extends Exception {
    
public SpecialException() {

    }

    
public SpecialException(String msg) {
        
super(msg);
    }
}

public class FinallyReturn {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        FinallyReturn fr 
= new FinallyReturn();
        System.out.println(fr.methodB(
1));// 打印100
        System.out.println(fr.methodB(2));// 打印100
    }

    
public int methodA(int money) throws SpecialException {
        
if (--money <= 0) {
            
throw new SpecialException("Out of money");
        }

        
return money;
    }

    @SuppressWarnings(
"finally")
    
public int methodB(int money) {
        
try {
            
return methodA(money);// 可能抛出异常
        } catch (SpecialException e) {
            
return -100;
        } 
finally {
            
return 100;// 会覆盖try和catch代码块的return语句
        }
    }

}

        BQ丢失异?br />
public class ExLoss {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        
try {
            System.out.println(
new ExLoss().methodB(1));// 打印100
            System.out.println("No Exception");
        } 
catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    
public int methodA(int money) throws SpecialException {
        
if (--money <= 0) {
            
throw new SpecialException("Out of money");
        }

        
return money;
    }

    @SuppressWarnings(
"finally")
    
public int methodB(int money) {
        
try {
            
return methodA(money);// 可能抛出异常
        } catch (SpecialException e) {
            
throw new Exception("Wrong");
        } 
finally {
            
return 100;// 会丢失catch代码块中的异?/span>
        }
    }
}

9.3 Java异常c?/h3> 所有异常类的祖先类为java.lang.Throwablec,它的实例表示具体的异常对象,可以通过throw语句抛出?br />
ThrowablecL供了讉K异常信息的一些方法,常用的方法包括:
  • getMessage() --q回Stringcd的异怿息?
  • printStachTrace()--打印跟踪Ҏ调用栈而获得的详细异常信息。在E序调试阶段Q此Ҏ可用于跟t错误?
public class ExTrace {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        
try {
            
new ExTrace().methodB(1);
        } 
catch (Exception e) {
            System.out.println(
"--- Output of main() ---");
            e.printStackTrace();
        }
    }

    
public void methodA(int money) throws SpecialException {
        
if (--money <= 0) {
            
throw new SpecialException("Out of money");
        }
    }

    
public void methodB(int money) throws Exception {
        
try {
            methodA(money);    
        } 
catch (SpecialException e) {
            System.out.println(
"--- Output of methodB() ---");
            System.out.println(e.getMessage());
            
throw new Exception("Wrong");
        }
    }
}

打印l果Q?br />
--- Output of methodB() ---
Out of money
--- Output of main() ---
java.lang.Exception: Wrong
    at chapter09.d0903.ExTrace.methodB(ExTrace.java:
45)
    at chapter09.d0903.ExTrace.main(ExTrace.java:
26)

ThrowablecL两个直接子类Q?br />
  • Errorc?-表示仅靠E序本n无法恢复的严重错误,如内存不等?
  • Exceptionc?-表示E序本n可以处理的异常?

9.3.1 q行时异?/h4> RuntimeExceptioncd其子c都被称行时异常Q这U异常的特点是Java~译器不会检查它Q会~译通过Q但q行时如果条件成立就会出现异常?br />
例如当以下divided()Ҏ的参数b?Q执?#8220;a/b”操作时会出现ArrithmeticException异常Q它属于q行时异常,Java~译器不会检查它?br />
    public int divide2(int a, int b) {
        
return a / b;// 当参Cؓ0Q抛出ArrithmeticException
    }
下面的程序中的IllegalArgumentException也是q行时异常,divided()Ҏx有捕获它Q也没有声明抛出它?br />
public class WithRuntimeEx {

    
/**
     * @param args
     
*/
    
public static void main(String[] args) {
        new WithRuntimeEx().divide(
10);
        System.out.println("
End");
    }

    
public int divide(int a, int b) {
        
if (b == 0) {
            throw new IllegalArgumentException("除數不能?");
        }

        
return a / b;
    }

}

׃E序代码不会处理q行时异常,因此当程序在q行时出Cq种异常Ӟ׃DE序异常l止。以上程序的打印l果为:
Exception in thread "main" java.lang.IllegalArgumentException: 除數不能?
    at chapter09.d0903.WithRuntimeEx.divide(WithRuntimeEx.java:
29)
    at chapter09.d0903.WithRuntimeEx.main(WithRuntimeEx.java:
23)

9.3.2 受检查异?/h4> 除了RuntimeException及其子类以外Q其他的Exceptioncd其子c都属于受检查异常(Checked ExceptionQ。这U异常要么catch语句捕获Q要么throws子句声明抛出Q否则编译出错?br />

9.3.3 区分q行时异常和受检查异?/h4> 受检查异常表C程序可以处理的异常?br />
q行时异常表C无法让E序恢复q行的异常,Dq种异常的原因通常是由于执行了错误操作。一旦出C错误操作Q徏议终止程序,因此Java~译器不查这U异常?br />

9.3.4 区分q行时异常和错误

Errorcd其子c表C程序本w无法修复的错误Q它和运行时异常的相同之处是QJava~译器都不会查它们,当程序运行时出现它们Q都会终止程序?br />
两者的不同之处是:Errorcd其子c表C的错误通常是由Java虚拟机抛出?br />
而RuntimeExceptionc表C程序代码中的错误,它是可扩展的Q用户可以根据特定的问题领域来创建相关的q行时异常类?br />

9.4 用户定义异常

9.4.1 异常转译和异帔R

public class BaseException extends Exception {

    
protected Throwable cause = null;

    
public BaseException() {

    }

    
public BaseException(String msg) {
        
super(msg);
    }

    
public BaseException(Throwable cause) {
        
this.cause = cause;
    }

    
public BaseException(String msg, Throwable cause) {
        
super(msg);
        
this.cause = cause;
    }

    
public Throwable initCause(Throwable cause) {
        
this.cause = cause;
        
return this;
    }

    
public Throwable getCause() {
        
return cause;
    }

    
public void printStackTrace() {
        printStackTrace(System.err);
    }

    
public void printStackTrace(PrintStream outStream) {
        printStackTrace(
new PrintStream(outStream));
    }

    
public void printStackTrace(PrintWriter writer) {
        
super.printStackTrace(writer);

        
if (getCause() != null) {
            getCause().printStackTrace(writer);
        }

        writer.flush();
    }
}

9.4.2 处理多样化异?/h4>
public class MultiBaseException extends Exception {

    
protected Throwable cause = null;

    
private List<Throwable> exceptions = new ArrayList<Throwable>();

    
public MultiBaseException() {

    }

    
public MultiBaseException(Throwable cause) {
        
this.cause = cause;
    }

    
public MultiBaseException(String msg, Throwable cause) {
        
super(msg);
        
this.cause = cause;
    }

    
public List getException() {
        
return exceptions;
    }

    
public void addException(MultiBaseException ex) {
        exceptions.add(ex);
    }

    
public Throwable initCause(Throwable cause) {
        
this.cause = cause;
        
return this;
    }

    
public Throwable getCause() {
        
return cause;
    }

    
public void printStackTrace() {
        printStackTrace(System.err);
    }

    
public void printStackTrace(PrintStream outStream) {
        printStackTrace(
new PrintStream(outStream));
    }

    
public void printStackTrace(PrintWriter writer) {
        
super.printStackTrace(writer);

        
if (getCause() != null) {
            getCause().printStackTrace(writer);
        }

        writer.flush();
    }
}

9.5 异常处理原则

9.5.1 异常只能用于非正常情?/h4>

9.5.2 为异常提供说明文?/h4>

9.5.3 可能地避免异常

9.5.4 保持异常的原子?/h4>

9.5.5 避免q于庞大的try代码?/h4>

9.5.6 在catch子句中指定具体的异常cd

9.5.7 不要在catch代码块中忽略被捕L异常Q可以处理异常、重新抛出异常、进行异常{?/h4>

CoderDream 2008-02-22 17:50 发表评论
]]> վ֩ģ壺 | ī| | | ͨɽ| | | | | | | | | | ¡| ̩| կ| | ־| Զ| | | | Ϫ| | ʡ| ƺ| | ɽ| | ʲ| | | | ͼ| ̨| | ̶| Խ| | ī񹤿|