异常及错误

现阶段遇到的异常
 JVM(java虚拟机)遇到异常后处理方式:
 1.先确定异常的类型,到类库中实例化一个该异常类型的对象
 2.看程序员(代码中)是否捕获此异常
      没有捕获:
           将异常信息直接打印到控制台中
      有捕获:
          程序员处理
package MONA.demo01_异常;

public class Demo01 {

    static String s;

    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        //ArithmeticException: / by zero:除以0异常
        //System.out.println(a / b);

        //NullPointerException :空指针
        //System.out.println(s.length());

        //ArrayIndexOutOfBoundsException:角标越界异常
        int[] arr = new int[1];
        System.out.println(arr[2]);
    }
}

 什么是异常?

异常就是Java程序在运行过程中出现的错误

异常的由来

问题也是显示生活中一个具体事务,也可以通过Java类的形式进行描述。

并封装成对象,其实就是Java对不正常情况进行描述后的对象体现。

例如:

医院的病种

异常的继承体系

在Java中使用Exception类来描述异常。Exception 类及其子类是 Throwable 的一种形式,它用来表示Java程序中可能会产生的异常,并要求对产生的异常进行合理的异常处理。

Exception有继承关系,它的父类是Throwable。Throwable是Java 语言中所有错误或异常的超类

异常类继承结构图

  1. Throwable(类)
    1. Error(错误):由JVM抛出,但不需要程序捕获,因为捕获了也没办法继续运行了;(比如堆栈溢出)
    2. Exception(异常):程序本身可以处理的异常
      1. 运行时异常:都是RuntimeException及其子类,如空指针、下标越界,这些异常是可以选择捕获处理,也可以不处理,一般是由程序逻辑引起的错误,应该从逻辑角度尽可能避免这类异常的发生
      2. 非运行时异常(编译时异常):RuntimeException以外的异常,从程序角度是必须进行处理的异常,如果不处理,那么编译就不能通过,如IOException;

 注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。

 演示错误的代码1:

package MONA.demo01_异常;

import java.util.ArrayList;

/**
 * 演示错误
 *  堆栈溢出:StackOverflowError
 */
public class Demo03 {
    static ArrayList<String> arr = new ArrayList<>();
    public static void main(String[] args) {
        add();
    }
    public static void add(){
        arr.add("111");
        add();
    }
}

编译器异常

package MONA.demo01_异常;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * 编译器异常
 */
public class Demo02 {
    public static void main(String[] args) throws ParseException {
        String date = "2002年10月09日";
        DateFormat df = new SimpleDateFormat();
        //df.parse(date);

        //错误
        int[] arr = new int[1024*1024*100];
    }
}

 

throw 抛出异常1

运行代码:

package MONA.demo01_异常;

public class Demo05 {
    public static void main(String[] args) {
    int[] arr = {1, 2, 3};
    int value = ArrayTools.getElement(arr,3);
        System.out.println(value);
    }
}

被使用的代码:

package MONA.demo01_异常;

public class ArrayTools {
    /**
     *获取数组中的指定下标的值
     * 此方法会发生两个异常:
     *      NullPointerException
     *      ArrayIndexOutOfBoundsException
     */
    public static int getElement(int[] arr,int index){
        //方法出现错误时,给调用者一个更具体的提示
        if(arr == null){
            //抛出异常  NullPointerException

            //1.创建异常对象
            NullPointerException e = new NullPointerException("arr不能为null");
            //2.使用throw抛出异常
            throw e;
        }

        //处理越界异常
        if(index < 0 || index >= arr.length){
            //抛出 ArrayIndexOutOfBoundsException越界异常
            ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("错误的下标["+index+"]");
            throw e;
        }
        return arr[index];
    }
}

throw 抛出异常2

运行代码:

package MONA.demo01_异常;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class Demo06 {
    public static void main(String[] args) throws ParseException{
        m1();
    }

    /**
     * df.parse(date);抛出异常
     * 有时候我们不想处理此异常
     *      throws关键字抛出异常
     *  让调用者来处理此异常
     */
    public static void m1() throws ParseException {
        String date = "2019年1月1日";
        DateFormat df = new SimpleDateFormat();
        df.parse(date);
    }
}

被使用的代码:

package MONA.demo01_异常;

import java.text.ParseException;

public class ArrayTools {
    /**
     *获取数组中的指定下标的值
     * 此方法会发生两个异常:
     *      NullPointerException
     *      ArrayIndexOutOfBoundsException
     */
    public static int getElement(int[] arr,int index)throws ParseException {
        //方法出现错误时,给调用者一个更具体的提示
        if(arr == null){
            //抛出异常  NullPointerException

            //1.创建异常对象
            NullPointerException e = new NullPointerException("arr不能为null");
            //2.使用throw抛出异常
            throw e;
        }

        //处理越界异常
        if(index < 0 || index >= arr.length){
            //抛出 ArrayIndexOutOfBoundsException越界异常
            ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("错误的下标["+index+"]");
            throw e;
        }
        if(true){
            //抛出的是编译器异常,所以在方法声明处必须使用throws关键字声明
            //方法抛出了此异常parseException
            ParseException parseException = new ParseException("我是异常",1);
            throw parseException;
        }
        return arr[index];
    }
}

异常捕获及其执行流程(单catch):

如果catch括号里面的异常类型跟try里的异常类型不对应,将不能捕获,即不会跳转到catch。

package MONA.demo01_异常;

/**
 * 异常捕获
 */
public class Demo07 {
    public static void main(String[] args) {
        /*
           try{
               可能出现异常的代码

           }catch(异常类型 变量名){
               //异常的处理
           }
         */

        String s = null;
        System.out.println("try之外的代码");
        try {
            System.out.println("异常之前的代码");
            System.out.println(s.length());
            System.out.println("异常之后的代码");
        }catch (NullPointerException e){//针对空指针异常进行处理
            System.out.println("发生了空指针异常");
        }
        System.out.println("程序结束!!!");
        /*
            执行流程:
                无异常:(catch没有执行)
                    try 之前的代码
                    异常之前的代码
                    执行可能出现异常的代码(没有出现异常)
                    异常之后的代码
                    程序结束!!!
                有异常:
                    try 之外的代码
                    异常之前的代码
                    try 里面的代码(某一行发生了异常)
                    跳转catch,执行catch里面的代码(如果捕获了异常)
                    try后续的代码 (程序结束!!!)
         */
    }
}

多catch捕获异常:

package MONA.demo01_异常;

/**
 * 多catch
 */
/*
        try{
            //可能出现多个异常的代词
        }catch (异常类型1 e){
            //处理异常类型1
        }catch (异常类型2 e){
            //处理异常类型2
        }
 */
public class Demo08 {
    public static void main(String[] args) {
        String s = null;
        int[] arr = {1,2};

        try{
            System.out.println(10/0);
            System.out.println(s.length());
            System.out.println(arr[10]);
        }catch (NullPointerException e){
            System.out.println("发生了空指针");
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("发生了越界异常");
        }catch (ArithmeticException e){
            System.out.println("除0异常");
        }

        System.out.println("程序结束");
    }
}

注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求父类异常最上面。

父类拥有所有处理子类异常的能力

try{
    异常代码
}catch (子类异常类型1 e){
    子类1处理代码
}catch (子类异常类型2 e){
    子类2处理代码
}catch (父类异常类型 e){
    父类处理代码
}

try ... catch ... finally

package MONA.demo01_异常;

/**
try{
    可能会发生异常的代码
}catch (异常类型 e){
    异常处理
}finally {
    我无论是否发生异常,都会执行
}
 */
public class Demo10 {
    public static void main(String[] args) {
        String s = null;

        try{
            //打开了文件
            System.out.println(s.length());
        }catch (NullPointerException e){
            System.out.println("发生空指针");
        }finally {
            //无论如何,都会执行
            System.out.println("我无论是否发生异常,都会关闭文件");
        }
        System.out.println("程序结束");
    }
}

jdk7异常处理方式

package MONA.demo01_异常;

/**
 * jdk7 同时处理多个异常
 *
 * 语法:
 * try{
 *     //可能发生异常的代码
 * }catch(异常类型1 | 异常类型2  变量名){
 *     //多个异常处理方式
 * }
 */
public class demo11_异常_jdk7处理方式 {
    public static void main(String[] args) {
        String s = null;
        int[] arr = {1,2};
        try{
            System.out.println(arr[10]);
            System.out.println(s.length());
        }catch (NullPointerException | ArrayIndexOutOfBoundsException e){
            System.out.println("发生了异常");
            //也可以针对异常类型进行判断
//            if(e instanceof NullPointerException){
//
//            }
//            if(e instanceof ArrayIndexOutOfBoundsException){
//
//            }
        }
        System.out.println("程序结束");
    }
}

继承中父子类方法抛出异常问题

子类覆盖父类方法时,如果父类的方法声明异常,子类只能声明父类异常或者该异常的子类,或者不声明。

package MONA.demo12_异常_父子类方法;

import java.text.ParseException;

public class Demo {
}
class Fu{
    public void show() throws RuntimeException{
        System.out.println("show");
    }
}
class Zi extends Fu{
    public void show()throws ArrayIndexOutOfBoundsException{ }
    //错误示范
//    public void show()throws ParseException{
//
//    }
}

throwable常用方法

package MONA.demo13_异常_throwable;

public class Demo {
    public static void main(String[] args) {
        String s = null;
        try{
            System.out.println(s.length());
        }catch (NullPointerException e){
            String msg = e.getMessage();
            System.out.println("msg = "+msg);
            String toString = e.toString();
            System.out.println("toString ="+toString);
            System.out.println("==============================");
            //打印异常堆栈信息
            e.printStackTrace();
            System.out.println("==============================");
            //想要打印异常的信息
            System.out.println("空指针");
        }
    }
}

快速生成异常相关代码:

选中可能发生异常的代码再使用快捷键
快捷键:Ctrl+Alt+T

自定义异常

第一部分:测试类

package MONA.demo15_异常_自定义异常;

/**
 * 自定义异常
 * Java中提供了很多异常
 * 在开发中,也会出现很多异常
 *      人的年龄
 *      自定义:年龄不合法异常
 *
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        try {
            s.setAge(1000);
        } catch (AgeException e) {
            e.printStackTrace();
            System.out.println("发生异常了");
        }
    }
}
class Student{
    String name;
    int age;

    public void setAge(int age) {
        if(age<0 || age>150){
            //年龄不合法 抛出年龄不合法异常
            AgeException e = new AgeException("年龄不合法");
            throw e;
        }
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }
    
}

第二部分:自定义异常

package MONA.demo15_异常_自定义异常;

/**
 * 自定义异常:
 * 1.新建类
 * 2.继承异常类
 * 3.提供构造方法,传递异常信息
 */
public class AgeException extends RuntimeException{
    public AgeException(String msg){
        //调用父类的构造方法
        super(msg);
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值