异常大致有以下几种:
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
分类
所有的异常类是从 java.lang.Exception
类继承的子类。
- Java的异常(Exception和Error)分为检查异常和非检查的异常。
编译器要求你必须处理的异常。比如我们在编程某个文件的读于写时,编译器要求你必须要对某段代码try….catch… 或者 throws exception,这就是检查异常,简单的来说,你代码还没有运行,编码器就会检查你的代码,对可能出现的异常必须做出相对的处理。
除了RuntimeException
与其派生类(子类),以及错误(Error)。其他的差不多都是检查异常。
编译器不要求强制处置的异常,虽然有可能出现错误,但是不会在编译的时候检查。
RuntimeException
与其子类,以及错误(Error)
- Exception异常进行划分,它可分为运行时异常和非运行时异常。
都是RuntimeException
类及其子类异常,如NullPointerException
(空指针异常)、IndexOutOfBoundsException
(下标越界异常)等,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它。
RuntimeException
以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException
、SQLException
等以及用户自定义的Exception异常,一般情况下不要自定义检查异常。
java 内置异常类
Java 语言定义了一些异常类在 java.lang
标准包中。
捕获异常
1 2 3 4 5 6 7 8 9
| try{ }catch(异常类型1 异常的变量名1){ }catch(异常类型2 异常的变量名2){ }finally{ }
|
当保护代码块中发生一个异常时,异常被抛给第一个 catch 块。如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。如果不匹配,它会被传递给第二个 catch 块。如此,直到异常被捕获或者通过所有的 catch 块。
无论是否发生异常,finally 代码块中的代码总会被执行。(finally
块不一定要有)
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ExcepTest{ public static void main(String args[]){ int a[] = new int[2]; try{ System.out.println("Access element three :" + a[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Exception thrown :" + e); } finally{ a[0] = 6; System.out.println("First element value: " +a[0]); } } }
|
throws/throw
throws 用来声明一个方法可能抛出的所有异常信息,throw 则是指拋出的一个具体的异常类型。
1 2 3 4 5 6 7 8 9 10
| import java.io.*; public class className { public void deposit(double amount) throws RemoteException { throw new RemoteException(); } }
|
抛出多个异常:
1 2
| public void withdraw(double amount) throws RemoteException, InsufficientFundsException
|
自定义异常
- 所有异常都必须是 Throwable 的子类。
- 如果希望写一个检查性异常类,则需要继承 Exception 类。
- 如果想写一个运行时异常类,那么需要继承
RuntimeException
类。
例:银行账户的模拟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import java.io.*;
public class InsufficientFundsException extends Exception { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import java.io.*;
public class CheckingAccount { private double balance; private int number; public CheckingAccount(int number) { this.number = number; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; } else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } public double getBalance() { return balance; } public int getNumber() { return number; } }
|
使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100..."); c.withdraw(100.00); System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); }catch(InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } } }
|