Java笔记:异常

本文详细介绍了Java中的编译时异常和运行时异常的区别,展示了如何自定义异常并用于方法调用的异常处理,以及try-catch和throws关键字的使用场景。
摘要由CSDN通过智能技术生成

这个不分很简单,也就是我们熟知的报错时提示的那一大串红色字体。Java中的异常大体可以分为两类。

一类是编译时异常(Exception),一种是运行时异常(RuntimeException)。

编译时异常:

即在编译阶段就会进行提醒,例:

  public static void main(String[] args) throws ParseException{
     

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse("2024-11-11 11:45");
}

这里在写代码时parse方法就会有红线标注提醒,表示这里很容易出错(但也不一定是错误的),比如上面书写的格式就没有错误,我们再三检查后发现没有错误,想继续运行程序的话,则需要用throws关键字将异常抛出,这样程序便可以正常运行了。

而运行时异常则不会在写代码时进行提醒,而是在写完运行后出现错误时再进行报错提醒。常见的错误有数组越界异常等。例:

  public static void main(String[] args) {
        //RunTimeException(运行时异常) 编译时不报错,运行时产生错误
        Integer.valueOf("abc");

        int[] arr = {11,22,33};
        //数组越界异常,同样也属于运行时异常
        System.out.println(arr[5]);

       }

那么,认识了两种异常后,我们便可以思考:既然我们通常遇到的错误都是Java底层帮我们写好的异常,那么我们可不可以自己来书写一个异常呢,当然可以,我们之前学过了自定义方法,那么,我们也可以自定义异常来提醒使用我们定义的方法的调用者可能出现的异常。

自定义异常:

前面说过,异常分为编译时异常和运行时异常,同理,我们自定义异常时也需要有一个异常类,而这个类也必须RunTimeException或Exception,才可以成为异常类。例:

 class AgelllegalException extends Exception {
    public AgelllegalException() {

    }

    public AgelllegalException(String message) {
        super(message);
    }
}




 class AgelllegalRuntimeException extends RuntimeException {
    public AgelllegalRuntimeException() {
    }

    public AgelllegalRuntimeException(String message) {
        super(message);
    }
}

这样,我们就定义好了两个异常类。

随后,我们再到测试类中,去完成一个案例来测试我们的自定义异常吧~

模拟需求:判断用户输入的年龄是否合法(如果合法提示输入合法,否则抛出异常提示)

public class ExceptionTest2 {
    public static void main(String[] args) {
    //需求:保存一个合法的年龄
        try {
            saveAge(160);
            System.out.println("底层执行成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("底层出现异常!");
        }
        //这里调用时也会有红线提醒报错,原理类似于之前的parse,
        //同样,也需要用try-catch或者throw处理
        try {
            saveAge2(256);
            System.out.println("saveAge2执行成功");
        } catch (AgelllegalException e) {
            e.printStackTrace();
            System.out.println("saveAge2执行错误!");
        }
    }
    public static void saveAge(int age){
        if (age>0&&age<150){
            System.out.println("年龄被保存成功"+age);
        }else {
            //用一个异常对象封装这个问题
            //throw抛出去这个异常对象
        throw new AgelllegalRuntimeException("/age is illegal,you age is "+age);
        }
    }
    public static void saveAge2(int age) throws AgelllegalException{
        if (age>0&&age<150){
            System.out.println("年龄被保存成功"+age);
        }else {
            //编译时异常本身在书写程序时就会提示,所以这里有红线,需要用throws方法处理
            //注意:throw抛出去这个异常对象
            //throws 用在方法上,抛出方法内部的异常
            throw new AgelllegalException("/age is illegal,you age is "+age);
        }
    }
}

好了,这样我们的自定义异常也就算是发挥作用了,那么,这两种异常定义的区别在哪里呢?

很简单,当你觉得这种错误比较弱智,一般人不会犯时,就用运行时异常。(比如数组越界,有一些基础的应该都不会犯这种低级错误吧......)而如果你觉得在你写的方法中很容易让人误解或者出现错误的地方,就用编译时异常。即在书写程序时就进行错误提醒,及时提醒操作者修改错误。

保证良好的编程习惯,在以后我们定义方法时,也书写一个配套的自定义异常,防止别人调用时出现错误,也提高了代码的健壮性。

好了,关于认识和定义异常差不多就说到这里了,那么接下来就是异常的处理了(总不能只提出问题,不解决问题吧)

前面我们说过,可以用throw或throws来抛出异常,值得注意的是,trows是用在出现异常的方法上,抛出异常。(重点:只能作用在方法上!!!),而throw则表示抛出异常对象,即我们自定义异常方法的对象。除了这两种抛出异常的方式之外,还有一种异常的处理,叫try-catch方法,包围可能产生异常的方法。那么,什么时候用throws,什么时候用try-catch呢,很简单。如果一个方法中嵌套了多个方法,那么从底层方法开始,不断向上抛出异常,而最外层方法则进行try-catch捕获。(简单理解:发现问题后逐层上报给领导,最上层的领导解决问题)

例:

public class ExceptionTest3 {
    public static void main(String[] args)  {
        try {
            test1();
        } catch (FileNotFoundException e) {
            System.out.println("您要找的文件不存在!");
            throw new RuntimeException(e);
        } catch (ParseException e) {
            System.out.println("您在解析时间时出现了问题!");
            throw new RuntimeException(e);
        }
    }
  public static void test1() throws FileNotFoundException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse("2024-11-11 11:45:14");
      System.out.println(d);
      test2();
    }
  public static void test2() throws FileNotFoundException {
        //读取文件
      InputStream is = new FileInputStream("D:/meinv.png");
      }

值得注意的是,throws可以同时抛出多个异常,catch也可以同时捕获多个异常,判断调用者触发的是什么异常。那么问题又来了,如果嵌套了很多个方法的话,那么抛出的异常也会非常多,看起来也未免太冗长了,那么此时我们就可以统一抛出Exception,因为Exception是所有异常的祖宗,那么所有异常都可以用Exception进行抛出,这样就避免了代码的冗长,看起来更简洁,书写起来也方便。

所以,上面的代码我们就可以修改成这样:

public class ExceptionTest3 {
    public static void main(String[] args)  {
        try {
            test1();
        } catch (Exception e) {
            system.out.println("您的操作有误!");
            throw new RuntimeException(e);
        }
    }
  public static void test1() throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse("2024-11-11 11:45:14");
      System.out.println(d);
      test2();
    }
  public static void test2() throws Exception {
        //读取文件
      InputStream is = new FileInputStream("D:/meinv.png");
      }

ok,以上就是异常的所有知识点啦,本笔记为自己学习时方便复习所记,欢迎大佬来纠错和交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值