java异常处理

参考java官网教程:The Java™ Tutorials java.util.logging.Logger使用详解

1. java异常处理包括trycatch, finally三个部分,try内是可能会产生异常的代码,例如数组访问,IO操作等等;catch是异常捕捉和处理部分;finally部分主要在于发生异常时候,用于处理异常以及清理(例如下面例子PrinterWriter流需要关闭)。

try {

} catch (ExceptionType name) {
   ...handler...
} catch (ExceptionType name) {

}
ExceptionType是异常类型,必须是继承自Throwable类。在handler中我们可以通过name引用异常获得相关信息,例如:
try {

} catch (IndexOutOfBoundsException e) {
    System.err.println("IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
    System.err.println("Caught IOException: " + e.getMessage());
}

 

2. handler不仅仅可以打印异常信息和挂起程序,还可以进行错误恢复(error recovery),让用户决定异常处理,通过chained exceptions传送异常到更高级别。

关于chained exceptions详细参考Chained Exceptions,其中涉及到打印日志和Stack Trace打印:

        try{
            int a[] = new int[2];
            System.out.println("Access element three :" + a[1]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("Exception thrown  :" + e);
            StackTraceElement elements[] = e.getStackTrace();
            for (int i = 0 , n = elements.length; i < n; i++){
                /*System.out.println("elements: " + i);
                System.err.println(elements[i].getFileName()+":" +
                elements[i].getLineNumber() + ">>" + elements[i].getMethodName());*/
                logger.log(Level.INFO, elements[i].getMethodName());
            }
            throw e;
        }

3. finally部分始终会运行,用于善后处理,这个实例中他负责关闭PrintWriter,如果PrintWriter已经打开。
catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null){
                // No IOException, Stream open
                System.out.println("PrintWriter closed!");
                out.close();
            }
            else{
                // Stream not open maybe for IOException
                System.out.println("PrintWriter not open!");
            }
        }
想要了解更多关于finally在资源释放方面作用,请看:try-with-resources Statement,这里我们提供一个示范

4. 综合应用请看一下例子:
    try {
System.out.println("Enter try statement: ");
out = new PrintWriter(new FileWriter("OutFile.txt"));

for(int i = 0; i < SIZE; i++){
out.println("Value at:" + i + list.get(i));
}
}catch (IndexOutOfBoundsException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
out.close();
以上加粗部分新建一个PrintWriter类指向文件输出流,并且获取list数组内容输出到输出流指定文件。因为涉及到新建文件以及获取数组内容,所以需要处理IndexOutOfBoundsException(数组越界)和IOException(IO异常)。我们可以通过触发异常来进行试验:
正常运行时候,程序会建立OutFile.txt文件,并且写入信息。结果如下
Enter try statement: 
Access element three :0
Out of the block

Process finished with exit code 0

OutFile.txt中内容如下:

Value at:0

Value at:1

Value at:2

Value at:3

 

4.1 我们通过预先在相关目录下建立OutFile.txt文件,并且修改权限为高于目前用户,例如"chown root OutFile.txt"将文件所有权改为root这样程序便会因为无法建立文件产生IO异常,如下:

Enter try statement: 
java.io.FileNotFoundException: OutFile.txt (Permission denied)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:110)
    at java.io.FileWriter.<init>(FileWriter.java:63)
    at oracle.ListOfNumbers.writeList(ListOfNumbers.java:28)
    at oracle.ListOfNumbers.main(ListOfNumbers.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

 

4.2 我们在通过"for(int i = 0; i < SIZE + 1; i++)"使数组越界,然后运行程序发现:

java.lang.IndexOutOfBoundsException: Index: 10, Size: 10
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.get(ArrayList.java:411)
    at oracle.ListOfNumbers.writeList(ListOfNumbers.java:31)
    at oracle.ListOfNumbers.main(ListOfNumbers.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Access element three :0
Out of the block 

 

附注代码:

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.*;

class MyLogHandler extends Formatter{
    public String format(LogRecord record){
        return record.getLevel() + ":" + record.getMessage() + "\n";
    }
}

public class ListOfNumbers{
    private List<Integer> list;
    private static final int SIZE = 10;

    public ListOfNumbers(){
        list  = new ArrayList<Integer>(SIZE);
        for(int i = 0; i < SIZE; i++){
            list.add(new Integer(i));
        }
    }

    void writeList() {
        PrintWriter out = null;
        try {
            System.out.println("Enter try statement: ");
            out = new PrintWriter(new FileWriter("OutFile.txt"));

            for(int i = 0; i < SIZE; i++){
                out.println("Value at:" + i + list.get(i));
            }
        }catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        out.close();

    }

    public static void main(String args[]) throws IOException{
        ListOfNumbers test = new ListOfNumbers();
        test.writeList();
        Logger logger = Logger.getLogger("oracle");
        logger.setLevel(Level.ALL);
        ConsoleHandler handler = new ConsoleHandler();
        handler.setLevel(Level.SEVERE);
        logger.addHandler(handler);
        FileHandler fileHandler = null;
        try {
            fileHandler = new FileHandler("/users/wsy/language/java/Exception/log.txt");
        } catch (IOException e) {
            System.err.println("Create FileHandler failed!");
            e.printStackTrace();
        }
        fileHandler.setLevel(Level.ALL);
        fileHandler.setFormatter(new MyLogHandler());
        logger.addHandler(fileHandler);

        try{
            int a[] = new int[2];
            System.out.println("Access element three :" + a[2]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("Exception thrown  :" + e);
            StackTraceElement elements[] = e.getStackTrace();
            for (int i = 0 , n = elements.length; i < n; i++){
                /*System.out.println("elements: " + i);
                System.err.println(elements[i].getFileName()+":" +
                elements[i].getLineNumber() + ">>" + elements[i].getMethodName());*/
                logger.log(Level.INFO, elements[i].getMethodName());
            }
            throw e;
        }

        System.out.println("Out of the block");
    }
}

 

posted @ 2015-11-03 20:49  快乐的小土狗  阅读(173)  评论(0)    收藏  举报