代码改变世界

Java中的异常及异常处理方法

2020-10-09 16:00  在上海的日子里  阅读(418)  评论(0编辑  收藏  举报

前言:

  本文主要讨论Java中的异常,因为java是一种强类型语言,其中的异常处理和Python语言中的异常处理还是有些许区别!!!

目  录

一、异常

二、JVM 默认的异常处理

三、异常处理之 Try...catch...

四、Throwable 的成员方法

五、编译型异常和运行时异常

六、异常处理之Throws

七、自定义异常类

 

一、异常

异常:就是程序出现不正常的情况

案例如下:

package itheima2;

public class ExceptionDemo {

    public static void main(String[] args) {
        // 调用方法
        test();
        
    }
    
    //定义方法 -- 注意:自定义方法必须有static修饰,但是自定义类中的方法不需要static 修饰
    public static void test() {
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);  //超出数组索引范围,
    }
    
    /*
     报错信息:
         Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
        at itheima2.ExceptionDemo.test(ExceptionDemo.java:14)
        at itheima2.ExceptionDemo.main(ExceptionDemo.java:7)
     */

}

二、JVM 默认的异常处理

// 如果程序出现了问题,我们没有解决。那么Java虚拟机JVM就会做默认处理

// 处理包括两个步骤:

/*
   1、将异常的名称、异常的原因和异常的位置输出在控制台
   2、停止程序的运行  
/*

三、异常处理之 Try...catch...

异常处理通常有两种方法:

  Try ... catch..  和   Throws

Try .. catch .. 格式及执行流程:

// try ...catch...异常处理
/*
         格式:
            try {
                可能出现异常部分的代码;
            } catch(异常类名  变量名) {
                异常的处理代码;
            }
        执行流程:
            从try里面的代码开始执行,出现异常后会生成一个异常类对象,并且将这个异常类对象交给java运行时系统;
            java运行时系统会去catch中找匹配的异常类对象进行异常处理;
            执行完异常处理的代码后程序会向下继续执行!!!
*/

案例:

package itheima2;

// try ...catch...异常处理
/*
         格式:
            try {
                可能出现异常部分的代码;
            } catch(异常类名  变量名) {
                异常的处理代码;
            }
        执行流程:
            从try里面的代码开始执行,出现异常后会生成一个异常类对象,并且将这个异常类对象交给java运行时系统;
            java运行时系统会去catch中找匹配的异常类对象进行异常处理;
            执行完异常处理的代码后程序会向下继续执行!!!
*/
public class ExceptionDemo1 {

    public static void main(String[] args) {
        // TODO 方法调用
        test();

    }
    
    public static void test() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]);  //超出数组索引范围,
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("索引错误,索引值超出数组的索引范围");
        }
    }

}

四、Throwable 的成员方法

Throwable 类是所有异常类的父类!如下图所示:

 

 

Throwable类成员方法及案例如下:

package itheima2;

/*
 * Throwable 的成员方法, Throwable 类是 所有异常类的父类
 *         public String getMessage()  返回throwable的详细信息字符串
 *         public String toString()    返回可抛出的简短描述(原因)
 *         public void printStackTrace()  将异常信息输出在控制台
 * 
 */
public class ExceptionDemo2 {

    public static void main(String[] args) {
        // TODO 
        System.out.println("开始:");
        test();
        System.out.println("结束:");
    }
    
    public static void test() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]);  //超出数组索引范围,
        } catch (ArrayIndexOutOfBoundsException e) {
//            System.out.println("索引错误,索引值超出数组的索引范围");
            
            //public String getMessage()  返回throwable的详细信息字符串
            System.out.println(e.getMessage());
            
            //public String toString() 
            System.out.println(e.toString());
            
            //public void printStackTrace()  将异常信息输出在控制台----最常用方法
            
            e.printStackTrace();  //注意:调用printStackTrace方法时会直接打印出字符串,没有返回值;因此可以直接调用
            /*
             * e.printStackTrace()  执行结果如下,可以看出和jvm默认的异常处理一样,但是程序不会终止,可以继续向下执行;
             * java.lang.ArrayIndexOutOfBoundsException: 3
                        at itheima2.ExceptionDemo2.test(ExceptionDemo2.java:22)
                        at itheima2.ExceptionDemo2.main(ExceptionDemo2.java:15)
             */
        }
    }

}

五、编译型异常和运行时异常

异常通常分为编译时异常和运行时异常

//编译时异常通常都是 Exception类及其子类,需要显示处理,不然无法编译无法执行

//运行时异常通常都是 RuntimeException类,不需要显示处理

编译时异常可以理解为:在代码编写过程中代码飘红,出现错误导致代码无法执行;

运行时异常可以理解为:代码在编写过程中没有出现错误,但是执行结果显示错误。

具体案例如下:

package itheima2;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

// 编译时异常和运行时异常
public class ExceptionDemo3 {

    public static void main(String[] args) {
        //
        method();
        method2();
        
    }
    
    //自定义方法
    public static void method() {
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);  //运行时错误: 编译通过,结果报错,可以直接在代码中修改
    }
    
    public static void method2() {
        try {
            String ss = "2020-10-09";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date a = sdf.parse(ss);  // 编译时错误:代码飘红--
            System.out.println(a);
            } catch (ParseException e) {
                e.printStackTrace();
            }
    }
        
    
    /*
     * sdf.parse() 报错信息:包括错误原因和错误位置
     *         java.lang.Error: Unresolved compilation problem: 
                    Unhandled exception type ParseException
                
                    at itheima2.ExceptionDemo3.method2(ExceptionDemo3.java:25)
                    at itheima2.ExceptionDemo3.main(ExceptionDemo3.java:12)
     */
}

六、异常处理之Throws

一般的异常使用try catch来处理,但是当遇到一些超出权限的异常时我们需要将异常抛出,比如说将异常抛给方法的调用者,由方法的调用者进行异常处理!!!

/*
     throws 异常处理格式如下:
               public void 方法名() throws 异常类名{
          } 注意: 该格式放在方法()的后面
*/

案例如下:

package itheima2;

/*
    throws 异常处理方法
        格式:
            throws 异常类名
        注意: 该格式放在 方法()的后面。案例如下:
*/
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo4 {

    public static void main(String[] args) {
        //
        method();
        //在方法调用的时候进行try catch 异常处理, 在方法编写的时候用throws 异常类名  ,将异常抛出
        try {
            method2();
        } catch(ParseException e) {
            e.printStackTrace();
        }

    }
    
    //运行时异常
    public static void method() {
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);  //运行时错误: 编译通过,结果报错,可以直接在代码中修改
    }
    
    
    //编译时异常
    public static void method2() throws ParseException{
        
        String ss = "2020-10-09";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date a = sdf.parse(ss);  // 编译时错误:代码飘红--
        System.out.println(a);
            
    }

}

七、自定义异常类

 自定义异常类就是继承Exception类,并给出无参和带参构造方法!

案例如下:

  自定义异常类:

package itheima2;

// 自定义分数异常类,继承Exception类
public class ScoreException extends Exception{
    
    //有参无参构造方法
    public ScoreException(){}
    
    public ScoreException(String message) {
        super(message);
    }

}

  教师类:

package itheima2;

//自定义教师类
public class Teacher {
    
    //成员方法
    public void checkScore(int score) throws ScoreException {      //利用throws来抛出异常,给方法调用者进行处理
        //执行判断过程
        if(score < 0 || score > 100) {
            //抛出异常信息,可以无参方法也可以是带参方法
//            throw new ScoreException();
            throw new ScoreException("给出的数值不在范围内");
        } else {
            System.out.println("成绩正常!");
        }
    
    }
}

  测试类:

package itheima2;

import java.util.Scanner;

public class TestDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入分数:");
        
        int score = sc.nextInt();
        
        //异常处理
        try {
            Teacher tt = new Teacher();
            tt.checkScore(score);
        } catch(ScoreException e) {
            e.printStackTrace();
        }

    }

}

/*
 执行结果如下:
    请输入分数:
        111
        itheima2.ScoreException: 给出的数值不在范围内
            at itheima2.Teacher.checkScore(Teacher.java:12)
            at itheima2.TestDemo.main(TestDemo.java:17)
*/