Java中关于自定义异常类的一些问题

Java中定义了大量的异常类,虽然这些异常类可以描述编程时出现的大部分异常情况,但是在程序开发中,有时还需要描述程序中特有的异常情况。为了解决这种情况,Java允许用户自定义异类。

一、首先自定义的异常类必需去继承Exception类或其子类。

二、在实际开发中如果没有特殊要求,自定义的异常类只需要继承Exception类。

例如:(随便写一个叫PrintfIsErrorException的自定义异常类,也就是能表明异常情况的名字)。

class PrintfIsErrorException extends Exception{
    public PrintfIsErrorException(){
        super();     //调用父类的默认无参数构造
       }
    public PrintfIsErrorException(String message){
        super(message);   //调用父类的有参构造
       }
}

注意:

1、这里super(message):String message的message是为了描述出异常对象的信息的,实际上是调用父类中指定的构造方法,给异常信息的String变量赋值。当某个对象调用有异常抛出的方法时,也就是try代码块中的程序发生了异常,系统会将异常的信息封装成一个异常对象,并将这个对象传递给catch代码块进行处理, catch代码块需要一个参数指明它能够接受的异常类型。这个参数必须是Exception类或其子类(也就是我们自定义的异常类),例如:()(1)catch(PrintfIsErrorException e){ System.out.println(e.getMessage());}

(2)catch(PrintfIsErrorException e){e.printStackTrace();}。

其中这个printStackTrace()方法就是用于打印错误堆栈信息,简单说就是打印你的错误在哪一行代码并输出异常的消息字符串。简单的说e是捕获的能处理的异常对象,再通过对捕获的异常类型进行处理。其中调用的String getMessage()方法,这个方法打印的参数就是之前传进来的message,也就是该方法返回异常的消息字符串。

2、之所以父类有这个方法,其实Exception的父类Throwable所提供的方法,它继承过来的,Throwable类是所有异常类的父类,它还有一个直接子类叫Error类,Error类代表的是程序中所产生的错误, Exception类代表程序中产生的异常。

3、也可以这样写,但没必要因为自己的父类有现成的嘛(就好像家里有钱,还去外面借钱干嘛)

class PrintfIsErrorException extends Exception{
    String message;
    public PrintfIsErrorException(){
       this.message="";
    }
    public PrintfIsErrorException(String message){
        this.message=message;
    }
    public String getMessage(){
        return message;
    }
}

三、throws关键字,声明该方法有可能发生异常,当调用者在调用该方法时,就明确的知道该方法有异常,必须在程序中对异常进行处理,否则编译无法通过。(如果写的那个方法自己进行了try...catch捕获处理,就不需要用throws声明,简单来说因为自己已经处理好,不需要调用者来对异常进行处理,但是一般这样做,一般在方法体内用throw关键字抛出异常实例,然后再用throws向上声明该方法可能有异常,也就是抛给调用者)

(1)注意用throws关键字在定义方法时的异常抛出的语法格式(下面举例如图)

 [访问修饰符] [其他修饰符]  返回值类型 方法名 (参数列表) throws 异常类1,异常类2,...{

         方法体

四、throw关键字抛出异常。但是注意用于方法内,抛出一个异常实例,注意且每次只能抛出一个异常实例。注意如果throw抛出的是Error、RuntimeException,或者它们的子类异常对象,则无需使用throws关键字或try...catch语句对异常进行处理。举例如下:(这里举例用到一个两数相除的方法)

public double divide()throws DivideIsZeroException { //向上抛出该方法可能会发生异常
            double sum;
            if(num2==0){
                throw new DivideIsZeroException("除数不能为0!");  //这里就是抛出异常实例
            }
            sum=num1/num2;
            return sum;
        }

在该方法体中就用到throw关键字抛出异常实例,如果后面在主函数中调用会进行捕获处理该异常的对象,然后通过方法输出异常消息字符串。这里面new DivideIsZeroException("除数不能为0!")传进的参数就是message。

五、案例分析:

创建类Calc,定义2个数属性以及一个符号属性,编写4个方法add、minus、multiply、divide,4个方法分别进行2个小数的加、减、乘、除运算.在主函数里面接受用户输入2个运算数、1个运算符,根据该运算符选择应该调用哪一个方法进行运算。

代码如下:(代码注释有解释)

public class Calc {
        double num1;
        double num2;
        String sign;    //分别代表输入的两个小数和输入的运算符
        public Calc(double num1,double num2,String sign){
            this.num1=num1;
            this.num2=num2;   //类实例化对象时自动调用
            this.sign=sign;
        }
        public double add(){  //两数相加
            double sum;
            sum=num1+num2;
            return sum;
        }
        public double minus(){  //两数相减
            double sum;
            sum=num1-num2;
            return sum;
        }
        public double multiply(){  //两数相乘
            double sum;
            sum=num1*num2;
            return sum;
        }
        public double divide()throws DivideIsZeroException {     //两数相除
                                                                 //向上声明,抛出异常,交给调用者去处理
            double sum;
            if(num2==0){
                throw new DivideIsZeroException("除数不能为0!");  //抛出异常实例
            }
            sum=num1/num2;
            return sum;
        }
        public double Sign()throws DivideIsZeroException{  //该方法用来判断输入的运算符,然后再根据运算符调用不同的运算方法返回结果值
            double count=0;
            if(sign.contains("+")){
                count=add();
            }
            if(sign.contains("-")){
                count=minus();
            }
            if(sign.contains("*")){
                count=multiply();
            }
            if(sign.contains("/")){
                count=divide();
            }
            return count;
        }
}
class DivideIsZeroException extends Exception{  //自定义异常类叫做”除数为0异常“,继承父类Exception
    public DivideIsZeroException(){
        //调用父类的默认无参数构造
        super();
    }
    public DivideIsZeroException(String message){
        super(message);//调用父类有参构造
    }
}

测试代码如下:(主函数在其之中)

import java.util.*;
public class Test02 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请分别输入两位小数和运算符:(输入时中间用空格分隔!)");
        while (sc.hasNext()) {  //作用是一直可以测试不同的输入
            String str[] = new String[3];
            for (int i = 0; i < 3; i++) {
                str[i] = sc.next();
            }
            double num1 = Double.parseDouble(str[0]);
            double num2 = Double.parseDouble(str[1]); //用到包装类Double的parseDouble(String s)静态方法,直接用类名调用,该方法就是将字符串转换为对应的基本类型的数据
            Calc c = new Calc(num1, num2, str[2]);
            try {
                System.out.printf(String.format("两个小数的运算结果为:%.4f(结果保留4位小数!)\n", c.Sign()));
            } catch (DivideIsZeroException e) {
                e.printStackTrace();
            }
        }
    }
}

测试输入(2.2 2.2)代码的运行结果如下图:

 也可以将catch代码块改成如下:

catch (DivideIsZeroException e) {
                System.out.println(e.getMessage());
            }

运行结果变成:(前面用的那个方法会打印错误堆栈信息,也就是会告诉你产生异常的位置,也就是你在哪个地方调用它,那时刚好出现了异常,在try中被捕获)

  • 16
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁岁岁平安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值