异常来源

• 语法错误Syntax Error
程序员在编程过程中使用编程语言语法不当。
• 编译时间错误Compile-time Error
阻止代码编译的错误,例如末尾缺少分号语句。
• 运行时错误Runtime Error
程序运行时发生的错误,例如数组索引边界外。
• 逻辑错误Logical Error
导致程序生成意外输出的错误,例如意外输出划分。
• 系统错误System Error
由系统引起的错误,例如系统内存不足。

简介

异常Exceptions
• 异常是运行时错误。
• 异常是表示错误类型的对象。
• 例如,数组索引 outbunds 异常、空指针异常。
• 意外异常可能导致程序异常终止。
• 处理异常可以使程序更加可靠,但是,另一方面,它可能会降低程序。性能。

Java内置了一套异常处理机制,总是使用异常来表示错误。

异常是一种class,因此它本身带有类型信息。异常可以在任何地方抛出,但只需要在上层捕获,这样就和方法调用分离了:

try {
    String s = processFile(“C:\\test.txt”);
    // ok:
} catch (FileNotFoundException e) {
    // file not found:
} catch (SecurityException e) {
    // no read permission:
} catch (IOException e) {
    // io error:
} catch (Exception e) {
    // other error:
}

因为Java的异常是class从继承关系可知:Throwable是异常体系的根,它继承自Object。Throwable有两个体系:ErrorExceptionError表示严重的错误,程序对此一般无能为力,例如:

OutOfMemoryError:内存耗尽
NoClassDefFoundError:无法加载某个Class
StackOverflowError:栈溢出

Exception则是运行时的错误,它可以被捕获并处理。

某些异常是应用程序逻辑处理的一部分,应该捕获并处理。例如:
NumberFormatException:数值类型的格式错误
FileNotFoundException:未找到文件
SocketException:读取网络失败

还有一些异常是程序逻辑编写不对造成的,应该修复程序本身。例如:
NullPointerException:对某个null的对象调用方法或字段
IndexOutOfBoundsException:数组索引越界
Exception又分为两大类:

RuntimeException以及它的子类;
RuntimeException(包括IOException、ReflectiveOperationException等等)

捕获异常

捕获异常使用try...catch语句,把可能发生异常的代码放到try {...}中,然后使用catch捕获对应的Exception及其子类:

import java.util.InputMismatchException;//输入不匹配异常
import java.util.Scanner;

public class test4 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        try {
            int nextInteger = sc.nextInt();
            System.out.println(nextInteger);
            while (sc.hasNext()) {
                String str = sc.next();
                if (str.equals("q"))
                    break;
                int value = Integer.parseInt(str);
                System.out.println(value);
            }
        } catch (InputMismatchException ime) {
            sc.close();
            ime.printStackTrace();
        } catch (NumberFormatException nfe) {
            sc.close();
            nfe.printStackTrace();
        }
        System.out.println("At the end of the program.");
    }
}

如果不知道需要捕获什么异常
java.lang.Exception包括了所有种类的异常

import java.util.InputMismatchException;//于是乎不在需要这个
import java.util.Scanner;

public class TestTryCatch {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        try {
            int nextInteger = sc.nextInt();
            System.out.println(nextInteger);
            while (sc.hasNext()) {
                String str = sc.next();
                if (str.equals("q"))
                    break;
                int value = Integer.parseInt(str);
                System.out.println(value);
            }
        } catch (Exception e) {
            sc.close();
            e.printStackTrace();
        }
        System.out.println("At the end of the program.");
    }
}

所有异常都可以调用printStackTrace()方法打印异常栈,这是一个简单有用的快速打印异常的方法。

多catch语句

可以使用多个catch语句,每个catch分别捕获对应的Exception及其子类。JVM在捕获到异常后,会从上到下匹配catch语句,匹配到某个catch后,执行catch代码块,然后不再继续匹配。

简单地说就是:多个catch语句只有一个能被执行。例如:

抛出异常

抛出异常:如果程序中出现了异常,没有办法将具体的异常打印出来,不做任何处理

 

捕获异常:如果程序出现了异常,就能够详细的打印是什么原因导致了异常并且能够做出相应的处理,能够显示详细的Log
如果代码是抛出异常的方式,在运行时出现异常,并且打印的Log不明显,可以改用try{}catch方式来捕获异常,打印出详细的信息
throws语句   
throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常。对大多数Exception子类来说,Java 编译器会强迫你声明在一个成员函数中抛出的异常的类型。如果异常的类型是Error或 RuntimeException, 或它们的子类,这个规则不起作用, 因为这在程序的正常部分中是不期待出现的。 如果你想明确地抛出一个RuntimeException,你必须用throws语句来声明它的类型。

小结

Java使用异常来表示错误,并通过try ... catch捕获异常;
Java的异常是class,并且从Throwable继承;
Error是无需捕获的严重错误,Exception是应该捕获的可处理的错误;
RuntimeException无需强制捕获,非RuntimeException(Checked Exception)需强制捕获,或者用throws声明;
不推荐捕获了异常但不进行任何处理。

异常处理

最后修改日期:2019年12月24日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。