【JavaSE 五】异常

五、异常

什么是异常

​ 导致程序的正常流程被中断的事件

异常的处理

​ try catch

​ 1、将可能抛出异常的代码放在try里
​ 2、如果没有异常,就会顺序往下执行,并且不执行catch块中的代码
​ 3、如果发生异常,try 里的代码会立即终止,程序流程会运行到对应的catch块中
​ 4、e.printStackTrace(); 会打印出方法的调用痕迹

​ 使用异常的父类进行catch

​ 所有异常都是Exception的子类,也可以用这个catch

​ 多异常捕捉

​ 有时候一段代码会抛出多种异常,解决办法就是多加一条catch代码块

​ 另一个种办法是把多个异常,放在一个catch里统一捕捉,使用|来分隔多个异常,需要通过instanceof 进行 判断具体的异常类型

​ finally

​ finally代码块,无论异常是否发生,该代码块一定会被执行

​ throws

​ 将该方法中的异常抛出去,抛给调用该方法的方法中,让上一级去处理

​ throw和throws的区别

​ throws 出现在方法声明上,而throw通常都出现在方法体内

​ throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一 定抛出了某个异常对象

异常的分类

​ 异常分为:可查异常,非可查异常(运行时异常和错误)

​ 可查异常:必须进行异常处理,不处理编辑器会报错

​ 运行时异常:不进行处理不会报错,Java之所以会设计运行时异常的原因之一,是因为下标越界,空指针这些运 行时异常太过于普遍,如果都需要进行捕捉,代码的可读性就会变得很糟糕

​ 错误:指的是系统级别的异常,不需要强制捕捉

自定义异常

​ 创建一个类,继承Exception,然后提供构造方法(可以有参也可以无参,参数就是异常信息,需要传递给父类)

​ 方法中抛出一个自定义的异常,并且在方法体中,判断何种状况抛出异常

public class test {
    public static void main(String[] args){
        try{
            te(3);
        }
        catch(MyException e){
            System.out.println("传递的值为3");
            e.printStackTrace();
        }
    }
    public static void te(int a) throws MyException {
        if(a ==3){
            throw new MyException("抛出异常了");
        }
    }
}

class MyException extends Exception{
    public MyException() {
    }
    public MyException(String message) {
        super(message);
    }
}

123

练习

1)自定义异常

对MyStringBuffer的插入和删除方法中的边界条件判断,用抛出异常来解决

例: insert(int pos, String b) , 当pos 是负数的时候,抛出自定义异常
需要实现自定义两种异常
IndexIsNagetiveException 下标为负异常
IndexIsOutofRangeException 下标超出范围异常

public class MyStringBuffer implements InterfaceStringBuffer {
    private char[] ch; //内部管理的个字符数组
    private int len; // 全局都要使用的数组内有效元素的个数

    public MyStringBuffer() {
        ch = new char[16];//创建对象要默认创建一个大小16的空数组
    }

    public MyStringBuffer(String str) {
        ch = new char[16];
        try{
            append(str);//当创建对象时传递了一个字符串,则调用内部的append去添加
        }
        catch (IndexIsOutofRangeException e){
            e.printStackTrace();
        }
        catch (IndexIsNagetiveException e){
            e.printStackTrace();
        }

    }

    @Override
    public void append(String str) throws IndexIsNagetiveException, IndexIsOutofRangeException {
        insert(len,str);
    }

    @Override
    public void append(char c) throws IndexIsNagetiveException, IndexIsOutofRangeException {
        insert(len,c);
    }

    @Override
    public void insert(int pos, char b) throws IndexIsNagetiveException,IndexIsOutofRangeException {
        insert(pos,String.valueOf(b));
    }

    @Override
    public void insert(int pos, String b) throws IndexIsNagetiveException,IndexIsOutofRangeException {
//        if(pos < 0 || pos>len){
//            return;
//        }
        if(pos <0){
            throw new IndexIsNagetiveException("位置为负值");
        }
        if(pos >len){
            throw new IndexIsOutofRangeException("位置超过最大值");
        }
        char[] c = b.toCharArray();
        char[] temp = new char[capacity()];
        while (len+c.length > temp.length){//一步一步扩容
            temp = new char[temp.length*2 + 2];//原数组要进行扩容
        }
        System.arraycopy(ch, 0, temp, 0, pos);
        System.arraycopy(c, 0, temp, pos, c.length);
        System.arraycopy(ch, pos, temp, pos + c.length, len - pos);
        ch = temp;
        len = len + b.length();
    }

    @Override
    public void delete(int start) throws IndexIsOutofRangeException, IndexIsNagetiveException {
        delete(start,len);

    }

    @Override
    public void delete(int start, int end) throws IndexIsOutofRangeException, IndexIsNagetiveException {
        /*
         * 总体思想就是清零ch数组
         * 再把删除后的数组元素一个一个append进去
         * 这样可以避免过分关注ch数组大小和有效元素的问题
         * 全部由append去处理,最终还是由insert处理
         * 所以insert一定要写全面一点
         */
        if (end - start <= 0) {
            return;
        }
        if (start < 0) {
            return;
        }
        if (end > len) {
            return;
        }
        char[] temp = ch; //把ch数组缓存
        ch = new char[16];//ch数组清零
        int lentemp = len;//长度缓存,到时循环时需要用到
        len = 0;//ch都清零了,配套的len也得清零
        for (int i = 0; i < start; i++) {
            append(temp[i]);
        }
        for (int i = end; i < lentemp; i++) {
            append(temp[i]);
        }
    }
    @Override
    public void reverse() {
        char[] temp = new char[capacity()];
        for (int i = 0; i < len; i++) {
            System.arraycopy(ch, i, temp, len - 1 - i, 1);
        }
        ch = temp;

    }

    @Override
    public int length() {
        return len;
    }

    public int capacity() {

        return ch.length;
    }

    public String toString() {
        char[] temp = new char[len];
        System.arraycopy(ch, 0, temp, 0, len);//避免打印后字符串后面有很多空字符
        return String.valueOf(temp);
    }
}

2)练习异常综合1

银行存取钱系统

test.java

public class test {
    public static void main(String[] args) {
        Account ac = new Account(1500);
        ac.deposit(2000);
        try{
            ac.withdraw(5000);
        }
        catch(OverdraftException e){
            System.out.println("余额不足,取款失败,透支额度为:"+e.getDeficit());
            e.printStackTrace();
        }
        ac.deposit(3500);
    }
}

Account.java

public class Account {
    private double balance;

    public Account(double init) {
        balance += init;
        System.out.println("创建了一个余额为" + balance + "的账户");
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amt) {
        System.out.println("存款金额:" + amt);
        balance += amt;
        System.out.println("余额为" + getBalance());

    }

    public void withdraw(double amt) throws OverdraftException {
        System.out.println("取款金额:" + amt);
        if (amt - balance > 0) {
            throw new OverdraftException("发生了透支行为", amt - balance);
        } else {
            balance -= amt;
            System.out.println("余额为" + getBalance());
        }

    }
}

OverdraftException.java

public class OverdraftException extends Exception{
    private double deficit;

    public OverdraftException(String message, double deficit) {
        super(message);
        this.deficit = deficit;
    }

    public double getDeficit() {
        return deficit;
    }
}
3)练习异常综合2

增加透支功能,存取时都要考虑透支额,需要上一题的Account和OverdraftException类

test.java

import java.util.Scanner;

public class test {
    public static void main(String[] args) {

        Scanner  s = new Scanner(System.in);
        System.out.println("请先创建一个银行账户");
        System.out.println("请输入初始金额:");
        double init = s.nextDouble();
        System.out.println("请输入透支额度:");
        double overdraftProtection = s.nextDouble();
        CheckingAccount ac = new CheckingAccount(init,overdraftProtection);
        while (true){
            System.out.println("请选择服务:1,取款    2,存款");
            int i= s.nextInt();
            switch (i){
                case 1:
                    System.out.println("请输入取款金额:"); 
                    double amt = s.nextDouble();
                    try{
                        ac.withdraw(amt);
                    }
                    catch(OverdraftException e){
                        System.out.println("余额不足,取款失败,透支额度为:"+e.getDeficit());
                        e.printStackTrace();
                    }
                    break;
                case 2:
                    System.out.println("请输入存款金额:");
                    double amt1 = s.nextDouble();
                    ac.deposit(amt1);
                    break;
                default:
                    System.out.println("输入有误!");
            }
        }
    }
}

CheckingAccount.java

public class CheckingAccount extends Account{
    private double overdraftProtection;
    private double overBalance;

    public CheckingAccount(double init, double overdraftProtection) {
        super(init);
        this.overdraftProtection = overdraftProtection;
        overBalance = overdraftProtection;
        System.out.println("并激活了透支额度为"+overdraftProtection);
    }

    public void withdraw(double amt) throws OverdraftException {

        if(amt <= this.balance){//如果正常取钱,调用父类的方法操作
            super.withdraw(amt);

        }else if(amt <= this.balance+overBalance){//如果需要透支一部分,则重新写withdraw
            System.out.println("取款金额:" + amt);
            overBalance = this.balance+overBalance-amt;
            this.balance = 0;
            System.out.println("透支额度剩余:"+overBalance);
            System.out.println("余额为" + getBalance());
        }else {//超出透支额度,抛出异常
            throw new OverdraftException("发生了透支行为", amt - this.balance);
        }

    }
    public void deposit(double amt) {
        if(overBalance == overdraftProtection){//如果没有透支,直接调用父类的方法
            super.deposit(amt);
        }else {
            if(amt<overdraftProtection-overBalance){//透支了,但存的钱不够还
                overBalance = overBalance+amt;
            }else {//还的钱可以冲抵透支的,还可以有余额
                balance  = balance+amt-(overdraftProtection-overBalance);
                overBalance = overdraftProtection;
            }
            System.out.println("存款金额:" + amt);
            System.out.println("余额为" + getBalance());
            System.out.println("透支额度剩余:"+overBalance);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值