处理异常

java程序设计中, 异常对象都是派生于Throwable类的一个实例, 如果java中内置的异常类不能够满足要求, 用户可以自己创建自己的异常类.

11 异常, 日志, 断言和调试_层次结构

Error 类层次结构描述了java运行时系统的内部错误和资源耗尽错误. 应用程序不应该抛出这种类型的对象, 如果出现了内部错误, 除了通知用户, 并尽力使程序安全地终止之外, 也没无能为力了, 这种情况很少出现.

需要主要关注的是 Exception层次结构, 这个层次结构分为两个分支: 有程序错误导致的异常属于 RuntimeException, 另外的属于另一个分支, 类似 IOException

RuntimeException: 例如 错误类型转换, 数组访问越界, 访问空指针 等等

如果出现 RuntimeException, 那肯定是你的问题, 应该检查程序, 例如数组越界等等.

IOException: 例如: 试图在文件尾部后面读取文件, 试图打开一个错误格式的URL, 试图根据给定的字符串查找Class对象, 而这个字符串表示的类并不存在.

IOException: 使用判断和try catch来进行处理, 比如错误格式的URL, 在使用之前, 你要首先判断这个格式是否符合URL规则.

如果遇到了无法处理的情况, 那么java的方法可以抛出一个异常. 例如: public FileInputStream(String name) throws FileNotFoundException

java语言规范将派生于Error类或RuntimeException类的所有异常称为未检查异常, 所有其他的异常称为已检查异常.

public Image loadImage(String s) throws EOFException, MalFormedURLException ( 抛出多个异常 )

11 异常, 日志, 断言和调试_异常处理_0211 异常, 日志, 断言和调试_单元测试_03
Public String readData(Scanner in) throws EOFException {
    while () {
        if (!in.hasNext()) {
            if (n < len) throw new EOFException();
        }
    }
}
View Code

创建异常类

class FileFormatException extends IOException {

  public FileFormatException() {}

  public FileFormatException(String gripe) {

    super(gripe);

  }

}

}

捕获异常

try{} catch() {}

11 异常, 日志, 断言和调试_异常处理_0211 异常, 日志, 断言和调试_单元测试_03
public void read(String filename) {
    try {
          InputStream in = new FIreInputStream(filename);
          int b;
          while ((b = in.read()) != -1) {
                 // process input
          }    
    } catch (IOException exception) {
         exception.printStackTrace();
    }

} 
View Code

finally 子句, 无论是否发生异常都会执行.

使用异常机制的建议

1) 异常处理不能代替简单的测试

2) 不要过分的细化异常

3) 利用异常的层次接口, 不要只抛出 RuntimeException, 应该找到适当的子类或者自己定义的类.

4) 不要压制异常

5) 在检测错误时, "苛刻比放任更好"

6) 不要羞于传递异常

调试技术

1) 打印变量值, System.out.println("x=" + x);   // 你想要查看哪个变量的值

2) 在每一个类中放置一个main方法, 针对每一个类进行单元测试. ( 查看单元测试的自己的具体blog)

3) 利用 throwable 类提供的 printStackTrace 方法, 可以从任何一个异常对象中获得堆栈情况.

4) 错误信息保存, java MyProgram 2>errors.txt  // 还是类似linux中得重定向

5) jconsole processID ( 这个processID 是进程号, unix 下用 ps 命令查看, windows 用任务管理器查看 ) 这样会有一个图形界面.

6) 使用调试器, 例如 exclipse 单步跟踪等