【java】新手必看一篇讲透throw和throws,讲得超细!

一、throw关键字用于抛出异常

1.1一个例子初步认识throw,请复制到编译器里感受一下

throw: 在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者

//实现一个获取数组中任意位置元素的方法

    public static int getElement(int[]array,int index){
        if (array==null){
            throw new NullPointerException("传递的数组为null");//抛出空指针异常
        }
        if (index<0 || index>=array.length){
            throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");//抛出数组越界异常
        }

        return array[index];
    }

测试该方法:

测试1:传入null指针

public static void main1(String[] args) {
    int[] array1 = null;
    getElement(array1,0);//测试NullPointerException
}

运行结果:

测试2:传越界下标

    public static void main1(String[] args) {
        int[] array2={1,2,3};
        getElement(array2,-1);//测试ArrayIndexOutOfBoundsException
    }

 运行结果:

这两个测试可以看出throw都很好的完成任务了呢,让程序及时止损,及时停下来

      这里的两个异常都是在程序执行期间发生的,称为运行时异常。 

     运行时异常:RunTimeException以及其子类对应的异常。(比如上文的NullPointerException、ArrayIndexOutOfBoundsException都是其子类)

//注意:运行时异常指的是程序已经编译通过得到 class 文件了, 再由 JVM 执行过程中出现的错误,就是你点了运行的小三角形之后发生的事情哦~

1.2 throw注意点

注意点①:throw必须写在方法体内部

例子:尝试把throw语句写在类里,方法外。

class TestDemo1 {
   throw new  RuntimeException("测试throw语句是否能写在方法外 ");
}

 由图可得:代码划红线,显然在方法外写throw语句会导致编译错误。所以不要把throw语句写在方法外。

这时候会有人问 :为什么throw必须写在方法体内部?
       解释:当你在一个方法中使用throw语句时,你是在告诉编程语言:“嘿,我在这个方法中发现了一个问题,我不知道怎么处理,但我会把这个问题抛给调用我的那个人去处理。”这意味着异常是与该方法的执行环境紧密相关的。
       如果你试图将throw语句放在方法外部,编程语言就会困惑:这个异常到底是从哪个方法抛出的呢?因为它不在任何方法的上下文中,所以编译器无法理解它应该被传递给谁来处理。
       所以,将throw语句放在方法内部是必须的,因为这样可以清晰地表示异常是与该方法相关的。这也使得异常处理更加有序和可控。

【关于异常的小拓展】:受查异常和运行时异常

        上面的代码划红线也是一种异常,称编译异常或受查异常(Checked Exception)
并且,注意代码划红线和代码变红的区别!

public static void main(String[] args) {
         System.out.printn("注意看代码是字体变红,而不是下面划横线");
     }

字体变红:语法错误或书写错误

       在计算机编程中,语法错误或书写错误通常不被认为是受查异常。受查异常通常是在程序运行时可以预测和捕获的异常,例如试图访问不存在的文件或者网络连接失败。语法错误是在编译或解释阶段就发生的,通常指的是代码不符合语言的语法规则。与受查异常不同,语法错误无法通过异常处理机制捕获和处理,而是需要在代码编写阶段就修复

注意点②:抛出的对象必须是Exception 或者 Exception 的子类对象

二、异常的处理方法1:throws声明异常

       我们不能只抛出异常,而不解决异常,现在讲讲两种异常处理方法之一throws语句。

       throws 用于异常声明当方法中出现编译异常时,我就是不想改我的代码,就要对编译器声明异常,相当于对编译器说我就是要这样编,请让我运行吧。

        编译器说:可以是可以,请你声明一下。

       相当于给编译器签一份免责声明。报错之后,编译器就可以说,不关我的事。

2.1一个例子感受throws:

class Example {
    // readFile()这个方法会抛出IOException异常
    public void readFile() {
        throw new java.io.IOException("File not found"); // 模拟抛出异常
    }

这时编译器不认了哦,报红线,暗戳戳说:你这有异常我不给你运行。

这时候我们需要告诉编译器,我头铁,我就要!

 class Example {

    // 这个方法会抛出IOException异常,紧跟方法名添加throws java.io.IOException不报错了
    public void readFile() throws java.io.IOException  {
        throw new java.io.IOException("File not found"); // 模拟抛出异常
    }
    

 注意点③:如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理 。

意思就是运行异常不用我们管!它都叫运行异常了,肯定能挺过编译的。JVM哥哥说剩下的它管。因此我们在编译阶段只需要处理受查异常!

      解释:如果在代码中遇到 RuntimeException或其子类的异常,而没有进行显式的处理,那么异常会沿着调用栈向上传播,直到达到调用栈的顶部,也就是 JVM 的运行环境。在那里,异常会导致程序终止,并打印出异常的堆栈信息。这样做的好处在于,它提供了一种简单的方式来处理未预料到的异常情况,例如空指针异常、数组越界异常等,而不需要程序员在每个可能发生异常的地方都显式地处理它们,从而简化了代码的编写和维护。

注意点④:throws必须跟在方法的参数列表之后 且声明的异常必须是 Exception 或者 Exception 的子类 。这一点跟throw的是对应滴。

注意点⑤:方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开。如果抛出多个异常类型具有父子关系,直接声明父类即可。

注意点⑥. 调用声明抛出异常的方法时,调用者必须对该异常进行捕获,或者继续使用throws抛出。

class Example {
    // 这个方法会抛出IOException异常
    public void readFile() throws IOException  {
        throw new IOException("模拟抛出异常"); // 模拟抛出异常
    }



public static void main(String[] args) throws IOException {
        Example example = new Example();
        example.readFile();
    }

 

看到没,mian方法里也要声明 throws IOExeption,不然会报错哦。

编译器说:我可是很聪明的哦,这里也要签免责声明,别以为我不知道这里有问题。一生严谨的编译器(大家鼓掌)。

当然这里也可以不声明,但是要进行异常捕获(这里涉及到另一种异常处理方法try-catch,这一篇专注throw、throws,需要看try-catch的关注别的博客哦)。

以上就是关于throw和throws的全部内容。求三连!!会鼓励到我!!

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值