天天看點

java中的異常--Exceptions in Java-- 第二部分

 然而,很多時候,你将希望傳達更多的錯誤資訊而不隻是一個java.lang中的類。通常這個異常類本身标志遇到這個不正确的情況。例如,如果一個被抛出異常擁有IllegalArgumentException異常。那就标志某些程式通過了一個非法的參數調用了這個方法。有的時候你想要指出一個遇到了非法的條件(這個非法條件沒有在java.lang中被定義)的方法。

Other times, however, you will want to convey more information about the abnormal condition than a class from java.lang will allow. Usually, the class of the exception object itself indicates the type of abnormal condition that was encountered. For example, if a thrown exception object has class IllegalArgumentException, that indicates someone passed an illegal argument to a method. Sometimes you will want to indicate that a method encountered an abnormal condition that isn't represented by a class in the Throwable family of java.lang.

 舉個例子,假設你正在些一個java程式模拟一個客戶虛拟喝咖啡。考慮有可能在喝咖啡的時候發生的異常。圖2層次結構展示了一個部分可能性。

As an example, imagine you are writing a Java program that simulates a customer of a virtual café drinking a cup of coffee. Consider the exceptional conditions that might occur while the customer sips. The class hierarchy of exceptions shown in Figure 2 represents a few possibilities.

Figure 2. Exception hierarchy for coffee sipping  喝咖啡異常層次圖

如果客戶發現咖啡是冷的,他會很不爽,你的程式能抛出TooColdException異常。另一方面,如果客戶發現咖啡太熱了,你的程式應該能抛出TooHotException異常。這些情況能被認為是異常,因為他們在喝咖啡中不是被希望的情況。(異常情況不是很罕見,僅僅是超出正常情況的事件)你的新異常類可能如下:

If the customer discovers, with dismay, that the coffee is cold, your program could throw a TooColdException. On the other hand, if the customer discovers that the coffee is overly hot, your program could throw a TooHotException. These conditions could be exceptions because they are (hopefully) not the normal situation in your café. (Exceptional conditions are not necessarily rare, just outside the normal flow of events.) The code for your new exception classes might look like this:

 // In Source Packet in file except/ex1/TemperatureException.java

class TemperatureException extends Exception {

}

// In Source Packet in file except/ex1/TooColdException.java

class TooColdException extends TemperatureException {

// In Source Packet in file except/ex1/TooHotException.java

class TooHotException extends TemperatureException {

這個溫度異常類層次圖聲明了三個新的異常類型提供給你程式。注意每個異常類自己表示這種不正常的溫度情況。 TooColdException 說明咖啡比較冷,TooHotException 說明太熱。同時也要注意TemperatureException 類擴充自Exception類而不是Throwable、Error或者其他在java.lang中的類。

This family of classes, the TemperatureException family, declares three new types of exceptions for your program to throw. Note that each exception indicates by its class the kind of abnormal condition that would cause it to be thrown: TemperatureException indicates some kind of problem with temperature; TooColdException indicates something was too cold; and TooHotException indicates something was too hot. Note also that TemperatureException extends Exception -- not Throwable, Error, or any other class declared in java.lang.

Throwing exceptions 抛出異常

抛出一個異常,你簡單使用throw加上一個異常的引用,例如:  throw new TooColdException();引用類型必須是Throwable 或者Throwable 的子類。

To throw an exception, you simply use the throw keyword with an object reference, as in:

                        throw new TooColdException();

The type of the reference must be Throwable or one of its subclasses.

下面代碼展示了客戶類VirtualPerson抛出異常的例子。如果咖啡沒有滿足類VirtualPerson裡設定的值,就會抛出異常。注意java除了throw還有一個throws 關鍵字。throw 關鍵字隻能被用來抛出一個異常。throws 關鍵字将在文章下面講解。

The following code shows how a class that represents the customer, class VirtualPerson, might throw exceptions if the coffee didn't meet the customer's temperature preferences. Note that Java also has a throws keyword in addition to the throw keyword. Only throw can be used to throw an exception. The meaning of throws will be explained later in this article.

 // In Source Packet in file except/ex1/VirtualPerson.java

class VirtualPerson {

    private static final int tooCold = 65;

    private static final int tooHot = 85;

    public void drinkCoffee(CoffeeCup cup) throws

        TooColdException, TooHotException {

        int temperature = cup.getTemperature();

        if (temperature <= tooCold) {

            throw new TooColdException();

        }

        else if (temperature >= tooHot) {

            throw new TooHotException();

        //...

    }

    //...

// In Source Packet in file except/ex1/CoffeeCup.java

class CoffeeCup {

    // 75 degrees Celsius: the best temperature for coffee

    private int temperature = 75;

    public void setTemperature(int val) {

        temperature = val;

    public int getTemperature() {

        return temperature;

Catching exceptions  捕獲異常

在java中捕獲異常,你寫了一個try 帶了一個或者多個catch 字句的代碼塊。每一個catch子句指定一個具體的要被處理的異常類型。try塊裡面的代碼被catch裡的異常關聯。如果try裡的代碼抛出一個異常,相關的catch子塊将會被java虛拟機調用。如果虛拟機找到一個可以處理的異常,程式就繼續執行這個catch塊中的代碼。

To catch an exception in Java, you write a try block with one or more catch clauses. Each catch clause specifies one exception type that it is prepared to handle. The try block places a fence around a bit of code that is under the watchful eye of the associated catchers. If the bit of code delimited by the try block throws an exception, the associated catch clauses will be examined by the Java virtual machine. If the virtual machine finds a catch clause that is prepared to handle the thrown exception, the program continues execution starting with the first statement of that catch clause.

舉個例子,考慮一個需要一個參數的指令行程式,一個string能被解析成一個integer類。當你有一個string并且想要一個int,你能調用Integer 中的parseInt()方法。如果你輸入的這個string代表為integer,parseInt() 将會傳回相應的值。如果這個sting不能代表一個integer,parseInt()方法就會抛出NumberFormatException異常。下面是實作代碼:

As an example, consider a program that requires one argument on the command line, a string that can be parsed into an integer. When you have a String and want an int, you can invoke the parseInt() method of the Integer class. If the string you pass represents an integer, parseInt() will return the value. If the string doesn't represent an integer, parseInt() throws NumberFormatException. Here is how you might parse an int from a command-line argument:

                        // In Source Packet in file except/ex1/Example1.java

class Example1 {

    public static void main(String[] args) {

        int temperature = 0;

        if (args.length > 0) {

            try {

                temperature = Integer.parseInt(args[0]);

            }

            catch(NumberFormatException e) {

                System.out.println(

                    "Must enter integer as first argument.");

                return;

        else {

            System.out.println(

                "Must enter temperature as first argument.");

            return;

        // Create a new coffee cup and set the temperature of

        // its coffee.

        CoffeeCup cup = new CoffeeCup();

        cup.setTemperature(temperature);

        // Create and serve a virtual customer.

        VirtualPerson cust = new VirtualPerson();

        VirtualCafe.serveCustomer(cust, cup);

這裡,parseInt() 調用包括在一個try塊中,try的附加塊是catch子句(捕獲異常NumberFormatException)

Here, the invocation of parseInt() sits inside a try block. Attached to the try block is a catch clause that catches NumberFormatException:

                        catch(NumberFormatException e) {

    System.out.println(

        "Must enter integer as first argument.");

    return;

小寫字元e代表了一個抛出異常對象NumberFormatException 的引用。這個引用能在catch塊中使用,盡管這個例子他沒有被使用。(catch塊的例子在文檔後面會被使用。

wercase character e is a reference to the thrown (and caught) NumberFormatException object. This reference could have been used inside the catch clause, although in this case it isn't. (Examples of catch clauses that use the reference are shown later in this article.)

如果使用者把Harumph 作為第一個參數給Example1 程式,parseInt() 将會抛出一個NumberFormatException 異常并且catch 塊将捕獲到這個異常,程式将會輸出Continued 。

If the user types Harumph as the first argument to the Example1 program, parseInt() will throw a NumberFormatException exception and the catch clause will catch it. The program will print:   Continued