Java教程

26.Java 异常机制(Error异常和Exception异常)/异常处理/try_catch_finally 异常处理/异常处理秘诀/IDEA程序调试

本文主要是介绍26.Java 异常机制(Error异常和Exception异常)/异常处理/try_catch_finally 异常处理/异常处理秘诀/IDEA程序调试,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

学习目标

异常机制

异常概念

本质是当程序出现异常错误时,程序能安全的退出、处理完后继续执行的机制。
异常处理即程序在出现问题时一九可以正确的执行完。

代码示例:异常处理小案例

package test.Exception;

public class Test01 {
    public static void main(String[] args) {
        System.out.println("step1");
        // 异常处理
        try{  // 利用 try 来处理异常
            int a = 1/0;   // 正常情况下是会报异常
        } catch (Exception e){ // 使用异常对象 e 来捕获异常
            e.printStackTrace();   // 使用 printStackTrace() 来打印捕获的异常信息
        }
        System.out.println("step2");
    }
}

Java 处理异常方式

1.抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,会停止当前执行路径,并把异常对象提交给 JRE。
2.捕获异常:JRE 得到该异常后,会寻找相应的代码来处理该异常。JRE 在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

异常分类

简述

JDK 中定义了很多异常类,这些类对应了各种各样可能出现的异常事件,所有的异常对象都是派生于 Throwable 类的一个示例。如果内置的异常类不能满足需求,还可以创建自己的异常类。
Java 对异常类进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类为 java.lang.Throwable。
Throwable 下又派生了两个子类 Error 和 Exception。(只需要管 Exception 即可)
Java 异常类的层次结构如下图所示:

Error 异常

Error 表示系统 JVM 已经处于不可恢复的崩溃状态中。不需要管。

Exception 异常

Exception 是程序本身能够处理的异常,如:空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算数异常(ArithmeticExveption)、数字格式异常(NumberFormatException)、数字格式异常(NumberFormatException)。
Exception 类是所有异常类的父类,其子类对应了各种可能出现的异常事件。
常见 Java 异常可分为:
(1)RuntimeException 运行时异常
(2)CheckedException 已检查异常

RuntimeException

由系统自动检测此类异常并将其交给缺省的异常处理程序(用户可不必对其处理)。
这类异常通常是由编程错误导致的,所以在编写程序时,不要求必须使用异常处理机制来处理这类异常,时常需要增加 “逻辑处理来避免这些异常”。

代码示例:算数异常(ArithmeticExveption):试图除 0

解决方案:

从逻辑上去处理这个异常,修改代码

package test.Exception;

public class Test02 {
    public static void main(String[] args) {
        int b = 0;
        if (b != 0 ){ // 增加一个非 0 判断来避免异常
            System.out.println(1/b);
        }
    }
}

代码示例:空指针异常(NullPointerException)

当程序访问一个空对象的成员变量或方法,或者访问一个空数组的成员时会发生空指针异常(NullPointerException)

解决方案:

解决空指针异常,通常是增加非空判断;

package test.Exception;

public class Test02 {
    public static void main(String[] args) {
        String str=null;
        if (str != null ){ // 增加一个非空判断来避免异常
            System.out.println(str.charAt(0));
        }
    }
}

代码示例:类型转换异常(ClassCastException)

在引用数据类型转换时,有可能发生类型转换异常(ClassCastException)

解决方案:

增加判断

package test.Exception;

public class Test02 {
    public static void main(String[] args) {
        Animal a = new Dog();
        if(a instanceof Cat) { //增加一个非空判断来避免异常
            Cat c = (Cat) a;
        }
    }
}

代码示例:数组下标越界异常(ArrayIndexOutOfBoundsException)

当程序访问一个数组的某个元素时,如果这个元素的索引超出了 0~数组长度-1 这个范围,则会出现数组下标越界异常(ArrayIndexOutOfBoundsException)

解决方案:

增加关于边界的判断来避免异常

package test.Exception;

public class Test02 {
    public static void main(String[] args) {
        int[] arr = new int[5];
        int a = 5;
        if(a < arr.length) { // 增加关于边界的判断来避免异常
            Syetem.out.println(arr[a]);
        }
    }
}

代码示例:数字格式异常(NumberFormatException)

在使用包装类将字符串转换成基本数据类型时,如果字符串的格式不正确,则会出现数字个数异常(NumberFormatException)。

解决方案:

引入正则表达式判断是否为数字。

package test.Exception;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test02 {
    public static void main(String[] args) {
        String str = "123sasd";
        Pattern p = Pattern.compile("^\\d+$");
        Matcher m = p.matcher(str);
        if (m.matches()){ // 如果 str 匹配到数字的正则表达式,才会转换
            System.out.println(Integer.parseInt(str));
        }
    }
}

异常注意事项:

CheckedException 已检查异常

所有不是 RuntimeException 的异常,统称为 CheckedException,又称之为 “已检查异常”。
比如 IOException、SQLException 等和用户自定义的 Exception 异常。
这类异常在编译时就必须做出处理与检查,否则无法通过编译。

两种处理办法:
(1)使用 “try/catch” 捕获异常。
(2)使用 “throws” 声明异常。

异常处理

异常处理一:try-catch-finally--捕获异常

捕获异常是通过 3 个关键词来实现的:try-catch-finally。
用 try 来执行一段程序,如果出现异常,系统抛出一个异常,可通过它的类型来捕捉(catch)并处理它,
最后一步是通过 finally 语句为异常处理提供一个统一的出口,finally 所指定的代码都要被执行。
注意点:
(1)catch 语句可有多个;
(2)finally语句只能有一个,根据自己的需求可写可不写;作用是释放资源。
(3)如果两个 catch 语句中的两个类有关系,则子类放前,父类放后。

异常处理图解:

过程详细解析如下:

当异常处理的代码执行结束以后,不会回到 try 语句去执行尚未执行的代码。

.

代码示例:try_catch_finally 异常处理

package test.Exception;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test03 {
    public static void main(String[] args) {
        FileReader reader = null;    // reader 初始化在try 之外定义,方便最后调用 close()
        try{
            // 定义 reader 引用对象,需要抛出异常
            reader = new FileReader("D:/阿jun.docx");
            // 第一次时读第一个内容(字母),read() 读出来是 int 类型,如果想看读的内容则需要强转为 char,同时需要抛出异常
            char c = (char)reader.read();
            // 读第二个内容(字母)
            char c2 = (char)reader.read();
            System.out.println("" + c + c2);
        }catch (FileNotFoundException e){
            e.printStackTrace();  // 打印异常
        }catch (IOException e){
            e.printStackTrace();  // 打印异常
        }finally{
            // 操作完成以后调用 close() 关闭资源
            try{
                if (reader != null){
                    reader.close();
                }
            }catch (IOException e){
                e.printStackTrace(); // 打印异常
            }
        }
    }
}

异常处理二:throws子句--声明异常

当 CheckedException 产生时,不一定立刻处理它,可以再把异常 throws 出去。

在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理。
如果一个方法中可能产生某种异常,但并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。
如果一个方法抛出多个已检查异常,则必须在方法的首部列出所有的异常,之间以逗号隔开。

代码示例:声明异常方式的异常处理

package test.Exception;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Test04 {
    // 声明异常方式的异常处理
    public static void main(String[] args)/* throws Exception */ {
        try {
            readFile(("D:/阿jun.docx"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void readFile(String path) throws Exception{
        FileReader reader = null;
        try {
            reader = new FileReader(path);
            char c = (char) reader.read();
            char c2 = (char) reader.read();
            System.out.println("" + c + c2);
        } finally {
            try{
                if (reader!=null){
                    reader.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

try-with-resource方法:自动关闭 Closeable 接口资源

JAVA中,JVM的垃圾回收机制可以对内部资源实现自动回收,给开发者带来了极大的便利。
但是JVM对外部资源(调用了底层操作系统的资源)的引用却无法自动回收,例如数据库连接,网络连接以及输入输出IO流等。
这些连接就需要我们手动去关闭,不然会导致外部资源泄露,连接池溢出以及文件被异常占用等。
JDK7之后,新增了"try-with-reasource"。它可以自动关闭实现了AutoClosable接口的类,实现类需要实现close()方法。
"try-with-resources声明",将try-catch-finally 简化为try-catch,这其实是一种语法糖,在编译时编译器仍然会进行转化为try-catch-finally语句。

代码示例:try-with-resource方法--自动关闭 Closeable 接口资源

package test.Exception;
import java.io.FileReader;

public class Test05 {
    public static void main(String[] args){
        try(FileReader reader = new FileReader("D:/阿jun.docx");){
            char c = (char) reader.read();
            char c2 = (char) reader.read();
            System.out.println("" + c + c2);
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

自定义异常

感兴趣的话自行了解。
主要是在自写框架时,会使用到自定义异常。

异常处理秘诀

利用搜索引擎解决异常问题,分四步走:
1.查看异常信息,确认异常种类和相关 Java 代码行号。
2.确定上下文相关的一些关键信息(疑难问题、需求),没搜到时就在搜索语法中加上关键词,再没搜到就删减关键词,扩大泛微。
3.拷贝异常信息,搜索引擎搜索异常问题。
遇到异常以后可以去记录下来形成一篇文章,方便后期查阅

IDEA程序调试

调试的核心是设置断点。
程序执行到断点时,会暂时挂起,停止执行。

.

.

.

.

这篇关于26.Java 异常机制(Error异常和Exception异常)/异常处理/try_catch_finally 异常处理/异常处理秘诀/IDEA程序调试的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!