目录
1.1 前言
throws 和 throw 一个字母之差,但使用的情况以及产生的效果却不相同,又可以说是相辅相成,异曲同工。
1.2 异常处理
异常(Exception)是程序中一些阻止程序正常运行的事件,严格地说,它不是错误(Error)。异常和错误是不一样的。Java 中通过异常处理机制来对异常进行处理。
throws 和 throw 就是异常处理机制中用于抛出异常的关键字。同时搭配 try - catch 块可以使得程序捕获的异常更加准确。虽然如果没有使用 try - catch 块也不会报错,这时使用 throws 和 throw 并没有多大的意义了。所以,使用了 throws 或 throw 都要搭配 try - catch 块。
1.3 throws
- 表示方法中可能抛出的异常;
- 用在方法(包括主方法)声明之后;
- 使用 try - catch 块捕获异常;
- 可以抛出多个异常的,用逗号分隔。多个异常可使用嵌套 try - catch 块来捕获多个异常;
- 在继承中,父类中的方法使用了 throws ,则子类中调用该方法的方法也需要用 throws 抛出相同的异常;(稍微解释一下原因,实际上,throws 是将异常抛给了该方法的调用者,因此调用者必须能收到同样的异常才行,因此调用者一定要用 throws 出和父类方法相同的异常。但是主方法比较特别,在主方法中调用父类中抛出异常的方法可以不用使用 throws ,因为异常都是由 Java 虚拟机 JVM 来处理的,主方法会自动将异常抛给 JVM 处理。)
class Parsent {
/*
父类方法抛出两个异常
*/
void msg() throws ArithmeticException, NullPointerException {
try {
int[] arry = new int[5];
// 由于 try 块的特性,程序到这出现异常就停止了,直接去到与第一个 try 块对应的 catch 块
int a = 50 / 0;
try {
arry[6] = 1;
}
catch (NullPointerException e) {
System.out.println(e);
}
}
catch (ArithmeticException e) {
System.out.println(e);
}
}
}
public class test1 extends Parsent {
/*
主方法可以不抛出异常
*/
public static void main(String args[]) {
test1 t = new test1();
t.msg();
}
}
运行结果:
java.lang.ArithmeticException: / by zero
这里要提一下的是,程序里命名抛出了两个异常,为什么只打印了一个异常,与 try - catch 块的特性相关。当遇到异常时, try 会终止运行,异常直接被 catch 块捕获。
1.4 throw
- 用在方法体中;
- 通常用来抛出用户自定义的异常;
- 程序在执行到throw语句时立即停止;
public class test1 {
void Adult(int age) {
if (age < 18) {
throw new ArithmeticException("该用户未成年");
}
else {
System.out.println("请稍等……");
}
}
public static void main(String args[]) {
test1 t = new test1();
try {
t.Adult(17);
}
catch (ArithmeticException e) {
System.out.println(e.toString());
}
}
}
运行结果:
java.lang.ArithmeticException: 该用户未成年
1.5 throws 和 throw 的异同(总结)
- 同:throws 和 throw 都是消极处理异常的方式。这里的消极并不是说这种方式不好,只是它们抛出的异常,都是由调用者处理而已;
- 异:
序号 | throws | throw |
---|---|---|
1 | 用在方法(包括主方法)声明之后 | 用在方法体中 |
2 | 执行 throws 抛出的是可能的异常,不一定会发生 | 执行 throw 一定抛出了某种异常 |
3 | 可以抛出多个异常 | 只能抛出一个异常 |