HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
  • 《PureJavaCoderRoad》

    • 导读

    • Java基础

      • Java入门

      • Java语法

      • Java流程控制

      • 面向对象

      • 异常处理

        • 1、Java异常
        • 2、异常处理
        • 3、自定义异常
    • Java进阶

    • Java高阶

    • 开发辅助工具

    • 计算机网络

    • 数据库

    • JavaEE

    • 中间件

    • 架构

    • 建议

  • PureJavaCoderRoad
  • Java基础
  • 异常处理
#异常处理
码农阿雨
2022-05-26
目录

2、异常处理

出现了Error会造成程序直接无法运行,所以捕获Error的异常的意义不大,毕竟你程序都直接挂了,捕捉了也没有很大的意义,你需要做的就是在开发环境提前观察、发现。

所以我们在编程的时候不用刻意预处理Error错误,但是出现了就必须解决。

异常的处理分两种:

  • 抛出
  • 捕获

# 异常抛出

异常的显式抛出使用throws关键字处理。

# throws关键字

throws 表示此方法不处理异常,而交给方法调用者进行处理。

简单地说就是 : 我这段代码很有可能会抛出错误,所以我用了 throws 把错误抛出,你要调用我的方法,你也要抛出错误。

语法:

public 返回值类型 方法名称(参数列表,,,)throws 异常类1,异常类2{

}

# throw关键字

throw 表示直接抛出一个异常,作用于方法函数内,如果异常没有捕获,则立马返回,把异常抛出给调用者。异常发生的时候,会立即返回,所以下面的代码就不会执行了。

接着上一章的例子,五菱宏光生产商知道我可能会把轮胎安装错误,于是它显式的告诉我:更换轮胎 有可能会出错,你必须要注意错误。

但是我并不在意,还是一意孤行,有错误就直接抛出吧。

throws、throw 是一种消极的异常处理

eg:

public class WuLingHongGuang {
    private String[] weels = {"左1", "左2", "后1", "后2", "备胎1"};
	
    //throws 关键字,表示更换轮胎方法可能会抛出异常
    void changeWeel(int index, String weelName) throws Exception { 
        if (index > weels.length) {
            throw new Exception("ERROR!!!轮胎安装位置错误了!"); //throw 关键字,位置错误 直接抛出异常
        }else {
            weels[index] = weelName;
        }
    }
}

class HaC {
    public static void main(String[] args) throws Exception { //addWeel() 会抛出异常,所以调用者也要处理这个异常,抛出 or 捕获
        WuLingHongGuang wuLingHongGuang = new WuLingHongGuang();
        wuLingHongGuang.changeWeel(10, "备胎2");
        System.out.println("更换成功"); //抛出了异常,就直接返回了,下面的代码不会执行
    }
}

输出:

Exception in thread "main" java.lang.Exception: ERROR!!!轮胎安装位置错误了!
	at com.hac.异常.WuLingHongGuang.changeWeel(WuLingHongGuang.java:13)
	at com.hac.异常.HaC.main(WuLingHongGuang.java:27)

可以看到,void addWeel(int index, String weelName) throws Exception 方法表示它可能会抛出错误,而在方法函数内 有一个判断,如果位置错误,就直接抛出 throw new Exception("ERROR!!!轮胎安装位置错误了!"),这可以很友好的把错误直接打印在控制台。

异常抛出后 ,System.out.println("更换成功"); 就不会执行了。

还有就是调用者Hac的main方法也需要抛出Exception,因为在这里Exception它是一个父类异常,它包含了CheckedException和unCheckedException,但是它并不知道是哪一个,所以一律需要处理,不然就不能通过编译。

可以看到,如果main方法不加throws Exception,会报错:

# 异常捕获

throw 只是抛出了异常,抛出给了调用者,调用者又简单的抛出了,但是调用者能否直接处理这个错误呢?抛出者能否直接处理这个异常而不是抛出呢?

答案是可以的,我们可以捕获这个异常。

异常捕获的关键字是 try-catch-finally

# try ... catch...finally 关键字

使用try来捕获有可能出错的代码,然后在catch里面进行处理。

语法:

try{
	//TODO
}catch(IOException e){
    //TODO 可能出错的代码
}catch(Exception e){
	//TODO
}finally{

}

注意点:

  1. finally可以不写,无论是否报错,finally最后一定会执行
  2. try不能单独存在,要么接catch,要么接finally
  3. 存在多个catch的时候,catch的顺序非常重要:异常的子类必须写在前面,因为只会执行一个catch。

我知道五菱宏光更换轮胎可能会出错,为了以防万一,我决定把错误捕捉,防止错误影响我的其他操作:

eg:

public class WuLingHongGuang {
    private String[] weels = {"左1", "左2", "后1", "后2", "备胎1"};

    void changeWeel(int index, String weelName) throws Exception { //throws关键字,表示方法可能会抛出异常
        if (index > weels.length) {
            throw new Exception("ERROR!!!轮胎安装位置错误了!"); //throw 关键字,直接抛出异常
        }else {
            weels[index] = weelName;
        }
    }
}

class HaC {
    public static void main(String[] args)  {
        WuLingHongGuang wuLingHongGuang = new WuLingHongGuang();
        try {
            wuLingHongGuang.changeWeel(10, "备胎2"); //捕获异常
            System.out.println("更换成功"); //报错并不会执行
        } catch (Exception e) {
            e.printStackTrace(); //把错误打印出来
        }finally {
            System.out.println("更换完毕...");
        }
    }
}

输出:

java.lang.Exception: ERROR!!!轮胎安装位置错误了!
	at com.hac.异常.WuLingHongGuang.changeWeel(WuLingHongGuang.java:13)
	at com.hac.异常.HaC.main(WuLingHongGuang.java:28)
更换完毕...

printStackTrace()表示打印方法的调用栈(方法之间的调用关系),对于调试错误非常有用,可以直接定位到出错的行数,上面输出的错误就是通过e.printStackTrace();输出的。

try ... catch...finally 是一种主动的异常处理方式

# RuntimeException和Exception的区别

有一天,五菱宏光的厂商告诉我,五菱宏光更换轮胎换错了也不是什么大事,你不用处理了,交给车的轮轴处理吧,反正也能转动(JVM),这种就是非检查异常 unCheckedException,而不是用户(程序员)处理。

对应代码就是抛出的异常改一下,改成RuntimeException,因为RuntimeException属于 unCheckedException,我可以处理,也可以不处理:

public class WuLingHongGuang {
    private String[] weels = {"左1", "左2", "后1", "后2", "备胎1"};

    void changeWeel(int index, String weelName) throws RuntimeException { //throws 关键字,表示方法可能会抛出异常
        if (index > weels.length) {
            throw new RuntimeException("ERROR!!!轮胎安装位置错误了!"); //throw 关键字,直接抛出异常
        }else {
            weels[index] = weelName;
        }
    }
}

class HaC {
    public static void main(String[] args)  { 
        WuLingHongGuang wuLingHongGuang = new WuLingHongGuang();
        wuLingHongGuang.changeWeel(10, "备胎2");//我不处理
        System.out.println("更换成功"); 
    }
}

当然我们这里可以写更准确的异常,这里应该是 ArrayIndexOutOfBoundsException (数组越界),它们的关系是这样的:

Exception
│
├─ RuntimeException
│  │
│  ├─ ArrayIndexOutOfBoundsException
│  │
│  ├─ NullPointerException

更加准确的写法(但是RuntimeException也已经足够了):

void changeWeel(int index, String weelName) throws ArrayIndexOutOfBoundsException { 
        if (index > weels.length) {
            throw new ArrayIndexOutOfBoundsException("ERROR!!!轮胎安装位置错误了!"); 
        }else {
            weels[index] = weelName;
        }
    }

两者区别:

非RuntimeException要求程序员写try-catch处理。如果不处理,程序将出现编译错误,是必须要处理才能运行的。

RuntimeException 不用try catch捕捉,但是万一出错将会导致程序运行中断。

所以说,只要某个方法throws 错误,我们应该积极处理。

# NullPointerException空指针异常

空指针是最常见的异常之一,表示该引用为null,即未赋值,未分配内存地址。一个为空的值去操作其他方法,就会出错,因为不知道你指向哪个对象。

eg:

class HaC {
    public static void main(String[] args)  {
        WuLingHongGuang wuLingHongGuang = new WuLingHongGuang();
        wuLingHongGuang = null; //把wuLingHongGuang 赋值 为null
        wuLingHongGuang.changeWeel(10, "备胎2"); // null调用其他就会报错
        System.out.println("更换成功"); 
    }
}

输出

Exception in thread "main" java.lang.NullPointerException
	at com.hac.异常.HaC.main(WuLingHongGuang.java:28)
阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#异常处理
上次更新: 2025-02-21 06:04:57
最近更新
01
《LeetCode 101》
02-21
02
IDEA、Golang、Pycharm破解安装
02-21
03
《LeetCode CookBook》
02-21
更多文章>
Theme by Vdoing | Copyright © 2020-2025 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式