异常是一种class,Throwable是异常体系的根,继承于Object。Throwable有两个体系:Error和Exception。
- Error表示严重的错误,程序对此一般无能为力,如:OutOfMemoryError(内存耗尽)、NoClassDefFoundError(无法加载某个Class)、StackOverflowError(栈溢出)等。
- Exception则是运行时的错误,可以被捕获并处理。分为两类:RuntimeException及子类、非RuntimeException(包含IOException、ReflectiveOperationException等等)。
- 一些异常是程序逻辑如:NumberFormatException(数据类型的格式错误)、FileNotFoundException(未找到文件)、SocketException(读取网络失败)等。
java规定必须捕获的异常包括Exception及其子类,但不包含RuntimeException及其子类。这类异常称为Checked Exception。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import java.io.UnsupportedEncodingException; import java.util.Arrays;
public class Throwable { public static void main(String[] args) { byte[] bs = toGBK("中文"); System.out.println(Arrays.toString(bs)); }
static byte[] toGBK(String str) { try { return str.getBytes("GBK"); } catch (UnsupportedEncodingException e) { UnsupportedEncodingException: System.out.println(e); return str.getBytes(); } } }
|
在方法定义时,使用throws表示该方法可能会抛出的异常类型。调用的时候必须强制捕获这些异常,否则编译器会报错。
1 2 3 4 5 6 7 8 9 10 11 12
| import java.io.UnsupportedEncodingException; import java.util.Arrays;
public class Throwable { public static void main(String[] args) throws UnsupportedEncodingException { byte[] bt=toGBK("你好"); System.out.println(Arrays.toString(bt)); } static byte[] toGBK(String str) throws UnsupportedEncodingException { return str.getBytes("GBK"); } }
|
捕获异常
用多个catch语句,每个catch分别捕获对应的Exception及其子类。子类的catch必须写在父类catch前面,要不然会被父类捕获。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Arrays;
public class Throwable { public static void main(String[] args) { try { byte[] bt = toGBK("你好"); System.out.println(Arrays.toString(bt)); } catch (UnsupportedEncodingException e) { System.out.println("编码不支持"); } catch (IOException e) { System.out.println("IO异常"); } } static byte[] toGBK(String str) throws UnsupportedEncodingException { return str.getBytes("GBK"); } }
|
当有无论是否发生异常都要执行的代码时,可以用finally语句保证执行,避免多写重复代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Arrays;
public class Throwable { public static void main(String[] args) { try { byte[] bt = toGBK("你好"); System.out.println(Arrays.toString(bt)); } catch (UnsupportedEncodingException e) { System.out.println("编码不支持"); } catch (IOException e) { System.out.println("IO异常"); }finally { System.out.println("不管你有没有报错,我都要输出"); } } static byte[] toGBK(String str) throws UnsupportedEncodingException { return str.getBytes("GBK"); } }
|
某些情况下,可以没有catch,只用try...finally结构。
遇到处理异常的代码一致的异常时,可以使用|分隔,但两者关系不能是类继承关系。
抛出异常
当某个方法抛出异常时,如果当前方法没有捕获异常,异常就会被抛到上层调用方法。


新的异常如果直接抛出而不关联原始异常, 才会导致原始异常信息被覆盖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package one; public class Throwable{ public static void main(String[] ages){ try{ fun2(); }catch(Exception e){ e.printStackTrace(); } } static void fun1(int a){ if(a==0){ throw new NumberFormatException(); } } static void fun2(){ try{ fun1(0); }catch(NumberFormatException e){ throw new IllegalArgumentException(); } } }
|
如果在执行finally分支语句时抛出异常,原本在catch中的准备抛出的异常就会被屏蔽,因为只能抛出一个异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package one; public class Throwable{ public static void main(String[] ages){ try{ fun1(0); }catch(Exception e){ throw new NumberFormatException(); }finally{ System.out.println("我先输出"); throw new IllegalArgumentException(); } } static void fun1(int a){ if(a==0){ throw new NumberFormatException(); } } }
|
自定义异常


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
| package one; public class Throwable{ public static void main(String[] ages){ try{ Login login=new Login("admin",null); }catch(LoginException e){ System.out.println(e.getMessage()); } } } class Login{ public Login(String username, String password){ check(username, password); } private void check(String username, String password){ if(username==null || password==null){ throw new LoginException("账号或密码不能为空"); } } } class LoginException extends RuntimeException { public LoginException() { super(); } public LoginException(String message) { super(message); } }
|