1. java所有异常分类
Exception
│
├─ RuntimeException
│ │
│ ├─ NullPointerException
│ │
│ ├─ IndexOutOfBoundsException
│ │
│ ├─ SecurityException
│ │
│ └─ IllegalArgumentException
│ │
│ └─ NumberFormatException
│
├─ IOException
│ │
│ ├─ UnsupportedCharsetException
│ │
│ ├─ FileNotFoundException
│ │
│ └─ SocketException
│
├─ ParseException
│
├─ GeneralSecurityException
│
├─ SQLException
│
└─ TimeoutException
2. 捕获异常
在Java中,凡是可能抛出异常的语句,都可以用
try ... catch
语句进行捕获。把可能发生异常的语句放在try { ... }
中,然后使用catch
捕获对应的Exception
及其子类。例如下面这样:
public static void main(String[] args) {
try {
process1();
process2();
process3();
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException e) {
System.out.println(e);
}
}
2.1. 捕获异常catch 的顺序
存在多个 catch 的时候,catch 的顺序非常重要:子类必须写在前面。例如下面这样:
这会导致UnsupportedEncodingException
这个异常永远捕获不到, 因为它是IOException的
子类,当抛出UnsupportedEncodingException
异常时,会被catch (IOException e) { ... }
捕获并执行,最后退出。
public static void main(String[] args) {
try {
process1();
process2();
process3();
} catch (IOException e) {
System.out.println("IO error");
} catch (UnsupportedEncodingException e) {
System.out.println("Bad encoding");
}
}
改正:
public static void main(String[] args) {
try {
process1();
process2();
process3();
} catch (UnsupportedEncodingException e) {
System.out.println("Bad encoding");
} catch (IOException e) {
System.out.println("IO error");
}
}
2.2. finally语句
无论是否有异常发生,如果我们都希望执行一些语句,
finally
语句块保证有无错误都会执行,希望执行的一些语句添加到finally
语句中。
public static void main(String[] args) {
try {
process1();
process2();
process3();
} catch (UnsupportedEncodingException e) {
System.out.println("Bad encoding");
} catch (IOException e) {
System.out.println("IO error");
} finally {
System.out.println("END");
}
}
3. 抛出异常
除了 JVM 检测到错误抛出异常之外,对于没有问题的语法我们也可以手动抛出异常,当程序执行到需要抛出异常的代码块时就会抛出我们手动添加的异常。写法可以像下面这样:
NumberFormatException ne = new NumberFormatException();
throw ne;
// 简洁写法
throw new NumberFormatException();
我们也可以对我们手动抛出的异常进行捕获
class GoogleAbnor {
public void googleAbnor(String s) throws NumberFormatException {
// NumberFormatException ne = new NumberFormatException();
// throw ne;
if (s == null) {
throw new NumberFormatException();
} else {
System.out.println("String fine");
}
}
}
class Abnor {
public void abnor() {
GoogleAbnor ga = new GoogleAbnor();
ga.googleAbnor(null);
}
}
public class AbnormalLearn {
public static void main(String[] args) {
GoogleAbnor gab = new GoogleAbnor();
try {
gab.googleAbnor("Hello");
} catch (Exception e) {
System.out.println("Catch NumberFormatException");
e.printStackTrace();
}
Abnor ab = new Abnor();
ab.abnor();
}
}
------------------------------------------------------------------------------------------------
执行结果:可以看到已经抛出了我们的异常
String fine
Exception in thread "main" java.lang.NumberFormatException
at com.zhbi.source.GoogleAbnor.googleAbnor(AbnormalLearn.java:10)
at com.zhbi.source.Abnor.abnor(AbnormalLearn.java:21)
at com.zhbi.source.AbnormalLearn.main(AbnormalLearn.java:38)
Java Result: 1
4. 异常的传递
当某个方法抛出了异常时,如果当前方法没有捕获异常,异常就会被抛到上层调用方法,直到遇到某个
try ... catch
被捕获为止,如上面的代码,我们可以使用try ... catch
来捕获我们手动抛出的异常,手动抛出的异常被捕获之后JVM就不再输出错误了。