Java基础之异常

​​​​​​​

目录

一、异常综述

二、Java异常处理关键字

1、try catch

2、finallly : 捕获异常后,进入这里

3、throw 关键字

4、throws关键字

 三、子类和父类异常情况

四、自定义异常

五、代码示例


​​​​​​​

一、异常综述


Object — Throwable |— Error :错误(内存溢出、系统奔溃),无法处理,尽量避免。红色警报
                                  |— Exception :异常,可以根据问题描述处理
                                          |— 编译时期异常:必须处理
                                          |— 运行时期异常(RuntimeException):一般会捕获处理,可以不处理默认交给JVM处理(不建议这么做,程序会终止)
                                                             |— NullPointerException :空指针异常
                                                             |— ArrayIndexOutOfBoundsException :超出数组下界

二、Java异常处理关键字

try catch,finally,throw,throws


1、try catch

      try{
         可能会出现异常的代码
       }catch(异常类型 变量名){
         处理异常的代码:记录日志、打印异常信息、继续抛出异常
       }catch(异常类型 变量名){}
     作用:捕获异常,尽量不要用JVM处理异常,因为程序会因此终止
     注意:
         1、try中可能抛出多个异常对象,可以使用多个catch处理异常信息
         2、如果try中产生多个异常


2、finallly : 捕获异常后,进入这里


     作用:不管发没发生异常都会执行finally中的内容都会被执行
     注意:☆ 如果有返回值,finally里一般不写return语句,因为会把try catch块里的return语句效果给覆盖掉。
                         建议将return语句放在方法结尾


3、throw 关键字


     作用:可以在方法中创建指定异常
     使用格式:throw new 异常类名(参数)
     注意:
         3.1 throw关键字必须写在方法内部
         3.2 throw关键字后面的new对象必须是异常
         3.3 throw关键字后面创建的是指定的异常
                              — RuntimeException或是它的子类对象: 可以不处理,交于JVM处理
                              — 编译时异常,必须处理,不能交于JVM处理,确保程序正常运行(抛出或try catch)
         3.4 先对入参进行细致的校验,如果产生问题,throw将问题描述类即异常抛出,将问题返回给该方法的调用者
             调用者进行捕获处理try catch ; 或继续将问题抛出


4、throws关键字

异常处理的一种方式,在方法后面抛出异常,把异常交于别人处理


     作用:当调用的方法抛出非运行时异常时,必须对这个异常进行处理
     注意:
     4.1 throws 关键字必须出现在方法的声明处
     4.1 throws 关键字必须是Exception对象或者Exception的子类
     4.3 方法内部如果有多个异常对象,那么throws后边必须也声明多个异常对象
            若多个异常对象存在父子关系,只需抛出父类
     4.4 调用者调用了一个声明异常的方法,可以选择不处理继续抛出,最终由JVM处理
         如若不然调用者必须使用try catch处理

 三、子类和父类异常情况

     1 若父类抛出异常,子类重写父类方法时,抛出和父类相同的异常或其子类或不抛出异常
     2 若父类没有抛出异常,子类重写父类方法时也不可抛出异常。此时子类产生的异常只能捕获处理(try catch),不能声明抛出(throws)

四、自定义异常

作用:根据具体业务的异常情况来定义。如年龄负数、考试负数等异常情况的处理

注意:
        1 自定义一个异常类,类名必须以Exception结尾
        2 如何自定义一个异常类
              2.1 自定义一个编译器异常:继承java.lang.Exception
              2.2 自定义一个运行期异常:继承java.lang.RuntimeException

五、代码示例

package com.bilibili.kegongchang.exceptions;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Objects;


public class DemoException extends Throwable{
    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) /*throws IOException*/{
        System.out.println("测试开始============================");
        // ArithmeticException :
        int i = 1;
        int k = 0;
        try {
            k = 2;
            k = 5;
            k = i / 0;
            k = 3;
        } catch (Exception e) {
            e.printStackTrace();//开发调试阶段:控制台打印异常的详细信息(异常的类型,异常的原因,异常出现的位置)
            System.out.println(e.getMessage());//提示给用户:获取发生异常的
            System.out.println(e.toString());//不用:获取异常的类型和异常描述的信息
        } finally {
            k = 1;
        }
        System.out.println(k);
        System.out.println("try catch 后程序会继续进行=====================");
        System.out.println("超出数组界限=====================");
        // ArrayIndexOutOfBoundsException : 超出数组界限
        //Exception-RuntimeException-IndexOutOfBoundsException-ArrayIndexOutOfBoundsException
        int[] arr = {1, 2, 3};
        int x = 0;
        try {
            x = getElement(arr, 3);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(x);

        System.out.println("子类异常和父类异常=====================");
        try {
            //readFile("");
            readFile("d:\\test\\FC10.xml");
        }catch (NullPointerException e) {
            e.printStackTrace();
        }catch (FileNotFoundException e) {// 父类异常包含子类异常,所以需要先抛子类再抛父类
            e.printStackTrace();
            e.getMessage();
            e.toString();
        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            System.out.println("finally中的内容被执行了=========");
        }

        System.out.println("Object 空指针==========================================");
        //Object obj = null;
        Object obj = new Object();
        Objects.requireNonNull(obj);
        System.out.println(Objects.requireNonNull(obj));
        System.out.println("Error:严重错误==========================================");

        // Error:严重错误,无法处理。只能修改源码
        // 内存溢出:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        int intArray[] = new int[1024*1024*1024];
        System.out.println("== 无法继续进行== ");

    }

    /**
     * 1、throw 先对入参进行校验,如果产生问题,throw将问题描述类即异常抛出,将问题返回给该方法的调用者
     * 2、调用者:进行捕获处理try catch ; 或继续将问题抛出
     * @param arr
     * @param index
     * @return 返回数组中对应下标的数字
     */
    public static int getElement(int[] arr, int index){
        if(arr == null){
            throw new NullPointerException("传递的数组不能为null!");
        }
        if (index < 0 || index > arr.length - 1){
            throw new ArrayIndexOutOfBoundsException("传递的数组索引越界!");
        }
        int element = arr[index];
        return element;
    }

    /**
     * Exception - IOException - FileNotFoundException
     * FileNotFoundException因为是子类,所以只需要抛出父类
     * @param fileName
     */
    //public static void readFile(String fileName) throws FileNotFoundException,IOException{
    public static void readFile(String fileName) throws IOException{
        // 1、校验
        // 1.1 校验名称不为空
        if (fileName == null || fileName.length() == 0){
            throw new NullPointerException("文件名称不能为空!");
        }
        // 1.2 校验文件是否存在
        File file=new File(fileName);
        if(!file.exists()){
            throw new FileNotFoundException("对应的文件不存在!");
        }
        // 1.3 校验文件后缀
        if (!fileName.endsWith(".txt")){
            throw new IOException("文件名称的后缀不是.txt");
        }

    }

}
package com.bilibili.kegongchang.exceptions;

/**
 * 自定义异常:
 */
public class RegisterException extends RuntimeException {
    public RegisterException(){
        super();
    }

    public RegisterException(String msg){
        super(msg);
    }
}
package com.bilibili.kegongchang.exceptions;

/**
 * 要求:我们模拟注册操作,如果用户已存在,则抛出异常并提示:亲,改用户名已经被注册
 * 分析:
 *      1、使用数组保存已经注册过的用户名称
 *      2、使用Scanner获取用户输入的注册用户名(web页面)
 *      3、定义一个方法,对用户输入的信息进行判断
 *          便利每个元素,获取用户名
 *          若存在返回 true :用户已存在,抛出RegisterException异常
 *            否则返回 false :继续遍历比较
 */
public class ExceptionTest {
    static String[] users = {"Jack","Nancy","Rose"};

    public static void main(String[] args) {
        boolean flag = false;// 是否注册成功
        try {
            flag = checkUserName("Jack");
        }catch (RegisterException e){
            e.printStackTrace();
            // 写入日志
        }
        try {
            flag = checkUserName("Shelly");
        }catch (RegisterException e){
            e.printStackTrace();
        }
        if (flag == true){
            System.out.println("ok");//去首页
        }else {
            System.out.println("no");//停留在注册页
        }
        System.out.println("程序继续====================");
    }

    public static boolean checkUserName(String userName){
        boolean flag = false;
        for(String user : users){
            if (user.equals(userName)){
                throw new RegisterException("亲,改用户名已经被注册!");
            }
        }
        System.out.println("欢迎"+ userName +",注册成功!");
        flag = true;
        return  flag;
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值