Java教程

Java-异常

本文主要是介绍Java-异常,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

异常

  • 就是程序不正常的情况

java中程序的异常:Throwable

  • Error:严重的问题,这样的情况,我们一般不做处理,因为这样的问题一般不是程序本身带来问题,而是外界导致。
  • Exception:
  • 1.编译时期异常:除了RuntimeException以外的异常都是编译时期异常,这样的异常必须做处理,如果不处理程序无法运行,编译无法通过
  • 2.运行时期异常:RuntimeException 这样的 问题我们可以不做处理,因为这是你自己的问题,通常情况下,出现这样的问题一般都是因为代码的逻辑不够严谨导致的。
出现问题后,如果我们没有做任何处理,JVM会提供一个默认的处理方式,可以看到出现了什么异常,出现异常的信息,以及出现问题的代码
public class ExceptionDemo1 {
    public static void main(String[] args) {
        //运行时期异常
        int[] arr = {11,22,33,44,55};
        System.out.println(arr[1]);
        System.out.println(arr[5]);

        System.out.println("hello");
    }
}

异常处理方案

  • 1、try…catch…finally
  • 2、throws

格式:

try…catch…finally处理格式:
           try{
               可能会出现问题的代码;
           }catch(异常的类名 变量名){
               针对出现的问题做处理;
           }finally{
               一般情况下,这里写释放资源;
           }
       变形格式:
           try{
               可能会出现问题的代码;
           }catch(异常的类名 变量名){
               针对出现的问题做处理;
           }

注意点

  • 1、try里面的代码如果出现问题,try里面的代码就会停在那一行,然后JVM会自动识别是什么问题,去catch匹配对应的异常,匹配到后执行对应的处理方式(catch大括号中的代码),如果没有匹配到,JVM会执行默认的处理方式,而默认的处理方式会将程序停止,后面的代码都不会执行
  • 2、try里面的代码越少越好,确定不会出错的代码就不要try里面写了。
  • 3、catch里面必须要有内容,哪怕就写了一个简单输出语句提示
public class ExceptionDemo2 {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
    //方式一:提前做一个判断
        if(b != 0){
            System.out.println(a/b);
        }else{
            System.out.println("被除数不能为0!");
        }
    //方式二:使用try。。。catch。。。
        try {
            System.out.println(a/b);
        } catch (Exception e) {
               e.printStackTrace();
//            System.out.println("你的除数为零了!");
        }
        //当对上面的异常进行处理之后异常之后的程序依旧会执行
        System.out.println("hello....");
    }
}

处理一个异常和处理多个异常

                try{
                    ...
                }catch(){
                    ...
                }catch(){
                    ...
                }

注意事项

  • 1、多个异常使用try..catch处理的时候,catch可以写一个,里面写最大的父类Exception,但是如果这么写了,try里面无论出现什么错误,都会匹配到这里的catch,这样的做的话,所有的问题处理方式都是一种处理,没法区分,不推荐这么做
  • 2、多个catch之间可以是继承关系,但是,要把父类的catch写在最后,因为出现问题匹配catch的顺序是自上而下的。
  • 3、JDK1.7之后出现了处理异常的新方案:
    try{
    放上可能会出现问题的代码;
    }catch(异常类名1|异常类名2|异常类名3|... 变量名){
    处理问题的代码;
    }

注意:

  • 1)新特性处理的方式并不太好,因为多种异常的处理方式统一是一种
  • 2)新特性的处理catch中的异常只能是平级关系,不能是继承关系
public class ExceptionDemo3 {
    public static void main(String[] args) {
        //编译时期异常
        String s = "2022-04-06 14:35:00";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        try {
//            Date date = sdf.parse(s);
//            System.out.println(date);
//        }catch (ParseException pe){
//            System.out.println("日期转换出错了!!!");
//        }
//
//        int[] arr = {11,22,33,44,55};
//        try {
//            System.out.println(arr[5]);
//        }catch (ArrayIndexOutOfBoundsException aiob){
//            System.out.println("取了不该取的索引");
//        }
        System.out.println("===============================================");
        //第二种处理方式:写一个try,多个catch

//        try {
//            Date date = sdf.parse(s);
//            int[] arr = {11, 22, 33, 44, 55};
//            System.out.println(arr[5]);
//        }catch (ParseException ae){
//            System.out.println("日期处理格式");
//        }catch (Exception ae){
//            System.out.println("取了不该取的索引");
//        }
        System.out.println("===============================================");
        //JDK1.7try..catch处理新方式
        try {
            Date date = sdf.parse(s);
            int[] arr = {11, 22, 33, 44, 55};
            System.out.println(arr[5]);
        }catch (ParseException|ArrayIndexOutOfBoundsException e){
            System.out.println("出错啦!!");
        }
        System.out.println("你好!!!");
    }
}
  • 分析问题: 在前面案例中,我们处理异常的方式都是输出一句话,告诉我们出了什么问题,但是呢,对比发现,并没有默认处理方式来的直接和清楚try..catch..的处理过程是,当try中的代码出现了问题的时候,JVM会帮助我们生成一个异常对象,然后把这个对象跑出来,与catch中的
    类型进行匹配,如果匹配到了,就走对应的处理方式。

异常中需要了解的几个方法:

  • 1、getMessage()
    获取异常信息,返回字符串。
  • 2、toString()
    获取异常类名和异常信息,返回字符串。
  • 3、printStackTrace()
    获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void
public class ExceptionDemo4 {
    public static void main(String[] args) {
        String str= "2020-04-05 19:23:45";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
//        try {
//            Date parse = simpleDateFormat.parse(str);
//        }catch (ParseException e) {
//            System.out.println("日期转换异常!");
//            String message = e.getMessage();
//            System.out.println(message); //Unparseable date: "2020-04-05 19:23:45" 无法解析时间
//
//            String s = e.toString();
//            System.out.println(s); //java.text.ParseException: Unparseable date: "2020-04-05 19:23:45"
//            //此对象的类的name(全路径名)
//            //": "(冒号和一个空格)
//            //调用此对象中的getLocalizedMessage()方法,底层调用的还是getMessage()方法。
//        }

        try {
            Date parse = simpleDateFormat.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("你好!");
    }
}

异常第二种解决办法:throws

  • 有些时候,我们可以对异常去做处理,但是呢,有些时候,我们根本就没有权限去处理这些异常。 或者说, 我们处理不了,就不处理了,交给更高权限的去处理。为了解决这样出错的问题,Java针对这种情况,就提供了另一种处理方案:抛出

格式

  • throws 异常类名
    注意:这个格式必须跟在方法的小括号后面,大括号前面。

注意:

  • 1、尽量不要在main方法上面抛出,因为main方法是由JVM调用的,如果出问题了,依旧是走默认的处理方式,
    而默认的处理方式,会将程序终止,后续代码不会执行,推荐能try..catch就try..catch
    (为了上课方便,后面的课程我就大部分在方法上抛出了)
  • 2、编译时期异常抛出,调用者必须要做处理,因为不做就没办法通过编译,就无法运行
  • 3、运行时期异常抛出,调用者可以不做处理,但是运行出了问题,程序终止,后续代码不会执行(推荐运行前检查代码逻辑,其次可以像处理编译时期异常一样try..catch)
throw: 在方法内部抛出,后面跟上具体的异常对象

面试题

  • throws:
    用在方法的声明后面,后面跟的是异常的类名
    异常的类名可以是多个,多个类名之间使用逗号隔开
    表示将异常抛出,交给调用者去处理
    throws表示的是一种可能性,并不一定会发生这些异常
  • throw
    用在方法的内部,后面跟的是异常的对象;
    只能是一个对象,不能抛出多个
    表示抛出异常,由方法内部的语句体去做处理
    throw表示的是方法内部一定会出现某种异常,是确定的。
public class ExceptionDemo5 {
    public static void main(String[] args){
//        try {
//            function();
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }catch(ArithmeticException ae){
//            ae.printStackTrace();
//        }

        try {
            function3();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("你好!");
    }
    public static void function3(){
        int q = 10;
        int p = 0;
        if(p != 0){
            System.out.println(q/p);
        }else{
           // System.out.println("除数为0");
            throw new ArithmeticException(); //确定一定会出问题,抛出一个对象
        }
    }


//    public static void function() throws ParseException,ArithmeticException{
//        String str = "2020-04-06 16:08:00";
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date date = simpleDateFormat.parse(str);
//
//        int a = 10;
//        int b = 0;
//        System.out.println(a/b);
    }

面试题:

  • finally,final,finalize他们三个你认识吗,他们什么什么区别?
    回答:都认识,但是他们三个之间没有任何关系,只是长得像罢了。finally是在异常处理中遇到,一般是用于释放资源的
    final是java中的一个关键字,他可以修饰类,成员变量,成员方法,修饰类,类不能被继承,修饰成员变量,
    变量变常量,修饰成员方法,方法不能被重写;finalize是Object类中的一个方法名,该方法是用于垃圾回收的
    但是什么时候回收不确定。
public class ExceptionDemo7 {
    public static void main(String[] args) {
        System.out.println(fun()); // a =
    }
    public static int fun(){
        int a = 20;
        int b = 0;
        try {
            a = 30;
            System.out.println(a/b);
            a = 40; // 这一行肯定不会执行
        }catch (ArithmeticException ae){
            a = 60;
//            ae.printStackTrace();
            return a;
            //当程序走到这里的时候,方法其实已经有了一个返回值路径,返回的就是60。
            //但是程序此刻还没有结束,所以依旧会走finally中的语句

        }finally {
            a = 50;
            System.out.println(a);
//            return a;
        }
        return a; // 这里其实是为了语法的正确,加了return
    }
}

继承中的异常

  • 1、子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
  • 2、如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
  • 3、如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

自定义异常

  • java中不可能把所有的情况都考虑到,所以在开发中,可能会自己定义异常
    但是我们,我自己随便写的一个类它仅仅是普通的类,不是异常类,于是需要继承Exception
    或者RuntimeException

MyException

public class MyException extends Exception{
    public MyException() {
    }

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

抛出 MyException

package com.shujia.java.day19;

import java.util.Scanner;

/**
 * @author xiaohu
 * @date 2021/08/14
 */

public class ExceptionStudentDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生的成绩:");
        int score = sc.nextInt();

        Teacher t = new Teacher();
        try{
            t.check(score);
        }catch (MyException me){
            me.printStackTrace();
        }


    }
}
这篇关于Java-异常的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!