java基础:异常处理

1. 什么是异常

异常就是程序执行过程中,因为某些原因导致程序不能正常执行,这些原因可能是:进行运算时除数为零,网络通信时连接中断,或JVM内存溢出等等。这些异常可能是因为用户引起的例如程序打算接收用户输入的数字,结果用户缺输入了其他字符,有的是程序错误引起的比如忘记写分号…

想要深刻理解java的异常处理机制,首先要理解以下三种类型的异常:

  • 运行时异常 :运行时异常是程序员可以解决的,可以在编译器被忽略,例如程序访问了没有初始化的对象的某个属性就会报出:java.util.NullPointException(空指针异常)
  • 检查性异常 :检查性异常是程序员无法解决的,这些异常不能再编译时被忽略,例如程序期望收到一个数字类型的数据,而用户输入了一个非数字类型字符,这样就会导致:java.util.InputMismatchException(输入不匹配异常)
  • 错误 : 错误不是异常。错误在代码中通常被忽略。例如,无线递归导致栈溢出时,一个错误就发生了,它们在编译也检查不到的。

2. Exception类的继承结构

所有的异常类是从 java.lang.Exception 类继承的子类。Exception 类是 Throwable 类的子类。除了Exception类外,Throwable 还有一个子类 Error 。Exception类有两个子类:IOException,RuntimeException。

Throwable
Exception
Error
IOException
RuntimeException

3. 常见的异常类型

异常描述
ClassNotFoundException应用程序找不到相应的类,抛出该异常
ArrayIndexOutOfBoundsException用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。
IndexOutOfBoundsException指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。

4. Throwable方法

方法描述
getMessage()返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
getCause()返回一个 Throwable 对象代表异常原因。
toString()返回此 Throwable 的简短描述。
printStackTrace()将此 Throwable 及其回溯打印到标准错误流。
getStackTrace()返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
fillInStackTrace()用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。

5. 捕获异常(try catch finally)

使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

public class App 
{
    public static void main( String[] args ) {
        File file = new File("config.yml");
        
        try {

            FileInputStream fileInputStream = new FileInputStream(file);
            
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("file文件不存在");
        }
    }
}

上面的代码捕获了FileNotFoundException异常try代码块中写入可能发生异常的语句,当程序捕获到异常将会停止执行异常语句之后的代码,从而执行finally代码块的方法。

也可以通过多个catch代码块来捕获多个异常。

try{
   // 程序代码
}catch(异常类型1 变量){
  // 程序
}catch(异常类型2 变量){
  // 程序
}catch(异常类型3 变量){
  // 代码
}

程序会根据系统捕获到的不同异常类型从而执行相应的方法。

6. throws/throw 关键字:

通过使用throws 和throw关键字可以抛出一个异常,交给上层代码处理。

如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

public class App 
{
    public static void main( String[] args ) throws FileNotFoundException {

        File file = new File("config.yml");
        
        FileInputStream fileInputStream = new FileInputStream(file);

    }
}

上面的代码将FileNotFoundException异常抛出。

如果程序设计者调用了一个会抛出异常的方法,要么处理这个异常,要么将异常继续抛出。

由方法抛出的异常交给系统处理(需要同学明确Java对异常强制检查要求的知识)
- Java 对 Exception 类中的异常可分为检查型异常和非检查型异常两类。

  • 非检查型异常都是RuntimeException类的子类,Java编译器对非检查型异常不要求进行捕获和处理也能通过编译;而不是RuntimeException类子类的异常则都是受检查型异常,例如方法抛出这类异常,调用者必须处理该异常。
  • 对于受检查型异常,如果调用者不处理,则必须在最后的 main 方法中将异常提交给系统。(上诉代码)

7. 自定义异常类型

通过继承 Exception类 可以自定义一个异常类型,从而提高程序安全性,自定义异常需要满足下列条件:

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

我们通过乔布斯买苹果手机来全面理解自定义异常

乔布斯手里拿了5000元想去苹果商店买一部iphone13但是,iphone13需要5399元,这样一来,乔布斯进入商店购买商品后就会引发异常。

消费者代码:

//消费者
class consumer{
    private String name;
    private int money;
    
    public consumer(String name, int money) {
        this.name = name;
        this.money = money;
    }
    public String getName() {
        return name;
    }
    public int getMoney() {
        return money;
    }
}

iphone13商店代码:

// 苹果手机
class iphone13{
    private int price;    // 价格
    private int inventory;    // 库存

    public iphone13(int price, int inventory) {
        this.price = price;
        this.inventory = inventory;
    }
    /**
     *   出售iphone13
     * @param shopingNum  购买数量
     * @param consumer  消费者信息
     * @return  购买状态
     * @throws InsufficientBalanceException  如果消费者没钱 抛出异常
     */
    public boolean sell(int shopingNum, consumer consumer) throws InsufficientBalanceException {
        if (this.inventory > 0 ){
            if (shopingNum * this.price < consumer.getMoney()){
                this.inventory -= shopingNum ;
                System.out.println("成功出售iphone" + this.price + "台, 商店库存:" + this.inventory);
            }else {

                // 在库存充足的情况下如果顾客余额不足以购买商品抛出异常...    <-- 重要代码
                throw new InsufficientBalanceException("顾客" + consumer.getName() + "余额不足,赶出商店...");
            }
        }
        System.out.println("出售失败,库存不足");
        return false;
    }
}

自定义异常代码:

// 当消费者余额不足是触发异常
class InsufficientBalanceException extends Exception{
    public InsufficientBalanceException(String message) {
        super(message);
    }
}

Main代码:

public class App {
    public static void main( String[] args ) {
        consumer Jobs = new consumer("乔布斯", 5000);
        iphone13 iphone13 = new iphone13(5399,20);

        //乔布斯想要买一个苹果手机
        System.out.println("乔布斯执意要买一个苹果手机,但是他只有5000元...");
        System.out.println("开始购买...");

        try { // 可能会发生异常的位置,将异常捕获     <-- 重要代码

            iphone13.sell(1,Jobs);

        } catch (InsufficientBalanceException e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("经过激烈的争吵后," + Jobs.getName() + "骂骂咧咧的离开了...");
        }
    }
}
C:\Users\Administrator\.jdks\jdk\bin\java.exe ...

乔布斯执意要买一个苹果手机,但是他只有5000元...
开始购买...
经过激烈的争吵后,乔布斯骂骂咧咧的离开了...
Exception in thread "main" java.lang.RuntimeException: org.example.InsufficientBalanceException: 顾客乔布斯余额不足,赶出商店...
	at org.example.App.main(App.java:73)
Caused by: org.example.InsufficientBalanceException: 顾客乔布斯余额不足,赶出商店...
	at org.example.iphone13.sell(App.java:52)
	at org.example.App.main(App.java:70)

进程已结束,退出代码1

点这里看更多精品java知识总结

以上就是java异常处理机制的基本理解,如有问题,欢迎指正。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值