Java的异常处理机制知识点【笔记详细】

1初始异常

1.1什么是异常?

  • 什么是异常,异常机制有什么用?
  • 1.以下程序执行过程中发生了不正常的情况,这种不正常的情况叫做:异常
  • java是很完善的语言,提供了异常的处理方式,以下程序原执行过程总出现了不正常情况
  • java吧该异常信息打印输出到控制台,工程许愿参考。程序员看到异常信息之后,可以对:
  • 程序进行修改,让程序更加健壮
  • 什么是异常:程序执行过程中的不正常情况
  • 异常的作用:增强程序的健壮性
  • 处理异常的第一种方式:
  •  在方法生命的位置上使用throws关键字抛出,谁调用我这个方法,我就抛给谁,抛给调用者来处理
    
  •  这种异常处理态度:上报
    
  • 处理异常的第二种方式:
  •  使用try...catch语句对异常进行捕捉
    
  •  这个异常不会上报,自己就把这个是处理了
    
  •  异常抛出到此为止,不再上抛了
    

1.2异常引例

public class Exception01 {

    public static void main(String[] args) {
        int a = 10;
        int b = 0;

        /*if(b==0){
            System.out.println("除数不能为0");
            return;
        }*/
        //程序执行到此处说明除数一定不为0
        int c = a/b;  //实际上JVA在执行到此处的时候,会new异常对象:new ArithmeticException(String s)
        //并且JVM将new的异常对象抛出,打印输出信息到控制台了
        System.out.println(100/0);   //此处也发生了new ArithmeticException(String s) 异常
        System.out.println(a + "/" + b + "=" + c);
    }
}

1.3执行结果

1.3.1结果展示

在这里插入图片描述

1.3.2结果说明

以下程序执行程序出现了:

  • Exception in thread “main” java.lang.ArithmeticException: / by zero
  • at com.power.javase.exception.Exception.main(Exception.java:22)
  • 这个信息被我们称为算术运算异常

2初始异常

2.1异常类创建异常对象

java语言中异常是以什么形式存在的呢?
每一个异常类都可以创建异常对象

2.2代码展示

public class Exception02 {
    public static void main(String[] args){
        //通过"异常类"实例化“异常对象”
        NumberFormatException nfe= new NumberFormatException("数字格式化异常!");
        System.out.println(nfe.toString());

        //通过"异常类"实例化“异常对象”
        NullPointerException npe = new NullPointerException("空指针异常");
        System.out.println(npe.toString());

    }
}

2.3执行结果

在这里插入图片描述

3运行时异常编写程序时可以不处理

3.1代码展示

注意: System.out.println(100/0);中100/0是运行时异常,可以不进行处理

package com.power.javase.exception;

/**
 * java 的异常处理机制
 *
 */

public class ExceptionTest03 {
    public static void main(String[] args) {
        /**
         *
         * 程序执行到此处发生了ArithmeticException异常,
         * 底层new了一个ArithmeticException异常对象,
         * 然后抛出了,由于是main方法调用了100/0,
         * 所以这个异常ArithmeticException抛给了main方法
         * main方法没有处理,将这个异常自动抛给了JVM,
         * JVM最终终止程序的执行
         *
         * ArithmeticException继承RuntimeException,属于运行时异常
         * 在编写程序阶段不需要对这种异常进行预先的处理
         */
        System.out.println(100/0);
        //这里的HelloWorld没有输出,没有执行
        System.out.println("Hello World");
    }
}

3.2执行结果

显示异常
在这里插入图片描述

4方法声明位置上使用throws【方法一】

  • 处理异常的第一种方式:
    在方法生命的位置上使用throws关键字抛出,谁调用我这个方法,我就抛给谁,抛给调用者来处理
  • 这种异常处理态度:上报

4.1代码展示

package com.power.javase.exception;
/*
以下代码标错的原因是什么?
    因为doSome()声明位置上使了:throws ClassNotFoundException
    而ClassNotFoundException(类没找到异常)是编译时异常。必须编写代码处理,没有处理
    编译器报错。
 */
public class ExceptionTest04 {
    public static void main(String[] args) throws ClassNotFoundException {
        /**
         * main()方法中调用doSome()方法
         * //因为doSome()方法声明位置上有:ClassNotFoundException
         * 我们在调用doSome()方法的时候必须对这种异常进行预先的处理
         * 如果我们不处理,编译器就会报错
         * 报错信息:
         * Error:(17, 15) java: 未报告的异常错误java.lang.ClassNotFoundException; 必须对其进行捕获或声明以便抛出
         */
        doSome();

    }
    /**
     * doSome方法在方法声明的位置上是用来:throws
     * 这个代码表示doSome()方法在执行过程中,有可能会出现ClassNotFoundException异常
     * 叫做类没找到异常,这个异常直接父类是:Exception,所以ClassNotFoundException属于编译时异常
     */
    public static void doSome() throws ClassNotFoundException{
        System.out.println("doSome!!!");
    }
}

4.2执行结果

成功调用
在这里插入图片描述

5try…catch捕捉异常【方法二】

使用try…catch语句对异常进行捕捉
这个异常不会上报,自己就把这个是处理了

5.1代码展示

package com.power.javase.exception;

public class ExceptionTest05 {
        //第一种处理凡是:在方法生命的位置上继续使用throws来完成异常的继续上抛,抛给调用者
    /*
        public static void main(String[] args) {
            doSome();
        }
    */
    //第二种处理方式:try ....catch 进行捕捉
    public static void main(String[] args) {
        try{
            doSome();
        }catch (ClassNotFoundException e){
            e.printStackTrace();

        }
    }
        public static void doSome() throws ClassNotFoundException{
            System.out.println("doSome!!!");
        }
    }

5.2执行结果

成功调用
在这里插入图片描述

6异常处理的原理

注意:只要异常没有捕捉,采用上报的发放时,此方法的

  • 希望调用者来处理,选择throws上报
  • 自己捕捉使用try…catch,不上报

6.1代码展示

package com.power.javase.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;


public class ExceptionTest06 {
    //一般不建议在main方法上使用throws,因为这个异常如果真的发生了,一定会传给JVM。JVM只有终止。
    //异常处理机制的作用就是增强程序的健壮性
    public static void main(String[] args) {
        System.out.println("main begin");
        try{
            //try尝试
            m1();
        }catch(FileNotFoundException e){
            //catch是捕捉异常之后走的分支
            System.out.println("文件不存在,可能路径错误,也可能是该文件被删除了!");
        }

        System.out.println("main over");
    }

    public static void m1()throws FileNotFoundException {
        System.out.println("m1 begin");
        m2();
        System.out.println("m1 over");
    }
    public static void m2()throws FileNotFoundException{
        System.out.println("m2 begin");
        //编译器报错原因是:m3()方法声明位置上有:throws FileNotFoundException
        //我们在这里调用m3()没有对异常尽心能够与处理,所以编译报错
        m3();
        System.out.println("m2 over");
    }
    public static void m3() throws FileNotFoundException {
        //创建一个输入流对象,该流指向一个文件
        /*
        编译时报错的原因是什么?
        第一:这个调用了一个构造方法:FileInputStream(String name)
        第二:这个构造方法的声明位置上有throws FileNotFoundException
        第三:通过类的继承结构看到:FileNotException父类是IOException,IOException的父类是Exception
        最终得知:FileNotFoundException是编译时异常
         */
        //new FileInputStream("D:\\a.txt");

        //我们采用第一种方式:在方法声明的位置上使用throws继续上抛
        //一个方法体当中的代码出现异常之后,如果上报的话,此方法结束。
        new FileInputStream("D:\\a.1txt");
    }
}

6.2执行结果

在这里插入图片描述

7深入try…catch

深入try…catch
1.catch后面的小括号中的类型可以是具体的异常类型,也可使该异常类型的父类型
2.catch 可以写多个。见一些catch的时候,精确的一个一个处理,这样有利于程序的调试
3.catch写多个的时候,从上到下必须遵守从小到大

7.1代码展示

public class ExceptionTest07 {
    private static Object ArithmeticException;

    public static void main(String[] args) {
        /*try{
            FileInputStream fis = new FileInputStream("D:\\a.1txt");
        }
        catch(IOException e){  //多态:IOExceptFileNotFoundExceptionion e = new  e
            System.out.println("文件不存在!");
        }*/

        /*try{
            FileInputStream fis = new FileInputStream("D:\\a.1txt");
            fis.read();
        }
        catch(FileNotFoundException e){  //多态:IOException e = new FileNotFoundException e
            System.out.println("文件不存在!");
        }
        catch(IOException e){
            System.out.println("读文件错了");
        }*/

        System.out.println("hellw world");


        //编译报错
        /*
        try{

            FileInputStream fis = new FileInputStream("D:\\a.1txt");
            fis.read();
            }
        catch(IOException e){
            System.out.println("读文件错了");
        }
        catch(FileNotFoundException e){  //多态:IOException e = new FileNotFoundException e
            System.out.println("文件不存在!");
        }*/

        //JDK8的新特性
        try {
            //创建输入流
            FileInputStream fis = new FileInputStream("D:\\a.1txt");
            //进行数学运算
            System.out.println(100 / 0);
        } catch (FileNotFoundException | ArithmeticException | NullPointerException e) {
            System.out.println("文件不存在!");
        }
    }
}

7.2执行结果

在这里插入图片描述

8异常对象的两个非常重要的方法

异常对象有两个非常重要的方法:
(1)获取异常简单的描述信息:
String msg = exception.getMessage();
System.out.println(msg);
(2) 打印异常追踪的堆栈信息:
exception.printStackTrace();

8.1代码展示

package com.power.javase.exception;
public class ExceptionTest08 {
    public static void main(String[] args) {
        //这里只是为了测试getMassage()方法和printStackTrace()方法
        //这里只是new了异常对象,但是没有将异常对象抛出。JVM会认为这是一个普通的java对象
        NullPointerException e = new NullPointerException("空指针异常fadil");

        //获取异常简单描述:这个信息实际上就是过偶早方法上面的String参数
        String msg = e.getMessage();
        System.out.println(msg);

        //打印异常堆栈信息
        //java后台采用异常堆栈追踪信息的时候,采用了异步线程的方式打印的。
        e.printStackTrace();
        System.out.println("hello world");
    }
}

8.2执行结果

在这里插入图片描述

9出现异常时,怎样快速调试

/*
异常对象有两个非常重要的方法:
获取异常简单的描述信息:
String msg = exception.getMeggage();
打印异常追踪的堆栈信息:
exception.printStackTrace();
我们以后怎么看异常的追踪信息,我们应该怎么看,可以快速的调试程序呢?
异常信息追踪信息,从上往下以下一行一行的看
但是需要注意的是:SUN写的代码就不用看了
*/

9.1代码展示

package com.power.javase.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;


public class ExceptionTest09 {
    public static void main(String[] args) {
        try{
            m1();
        }catch(FileNotFoundException e){
           //获取简单的描述信息
            String msg = e.getMessage();
            System.out.println(msg); //D:\a.1txt (系统找不到指定的文件。)

            //打印异常堆栈追踪信息
            //在实际开发中,建议使用这个,养成好习惯

          // e.printStackTrace();
           /*
           ava.io.FileNotFoundException: D:\a.1txt (系统找不到指定的文件。)
           at java.io.FileInputStream.open0(Native Method)
            at java.io.FileInputStream.open(FileInputStream.java:195)
            at java.io.FileInputStream.<init>(FileInputStream.java:138)
            at java.io.FileInputStream.<init>(FileInputStream.java:93)
            at com.power.javase.exception.ExceptionTest09.m3(ExceptionTest09.java:30)
            at com.power.javase.exception.ExceptionTest09.m2(ExceptionTest09.java:27)
            at com.power.javase.exception.ExceptionTest09.m1(ExceptionTest09.java:24)
            at com.power.javase.exception.ExceptionTest09.main(ExceptionTest09.java:16)
            30导致27,27导致24,24导致16,

            */
        }
        //这里程序不耽误执行,很健壮(服务器不会因为遇到异常而宕机)
        System.out.println("Hello World!");

    }
    public static void m1() throws FileNotFoundException{
        m2();
    }
    public static void m2() throws FileNotFoundException{
        m3();
    }
    public static void m3() throws FileNotFoundException{
        new FileInputStream("D:\\a.1txt");
    }
}

9.2执行结果

在这里插入图片描述

10读取文件时异常使用方法

关于try…catch中的finally字句:
1.在finally语句中的代码时最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常
finally字句必须和try一起出现,不能单独编写

2.finally语句通常使用在那些情况下呢?
通常在finally语句块中完成资源的释放/关闭
因为finally中的代码块比较有保障
即使try语句块中的代码出现异常,finally中代码也会正常执行
3.流使用完需要关闭,因为流是占用资源的,即使以上程序出现异常,流也是必须要关闭

10.1代码展示

package com.power.javase.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest10 {
    public static void main(String[] args) {
        FileInputStream fis = null; //声明位置放到try外面,这样在finally中才能用
        try{
            //创建输入流对象
            fis = new FileInputStream("D:\\a.1txt");
            //开始读文件...

            String s = null;
            //这里一定会出现空指针异常
            s.toString();

            //流使用完需要关闭,因为流是占用资源的
            //即使以上程序出现异常,流也是必须要关闭
            //放在这里有可能流关不了

        }catch(FileNotFoundException e){
            /*String stg = e.getMessage();
            System.out.println(stg);*/
            //e.printStackTrace();
            System.out.println(e.getMessage());   //2和3本质区别在于一个需要输出 System.out.println()函数
        }finally{
            System.out.println("Hello haoke");
            //流的关闭放到这里比较保险
            //finally中代码是一定会执行的
            //即使try中出现了异常!
            if(fis != null){    //避免空指针异常
                try{
                    //close()方法有异常,采用捕捉的方式
                    fis.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

10.2执行结果

正确的文件名是D:\a.txt,此处我指定的是错误的文件名(D:\a.1txt)
在这里插入图片描述

11 try-catch- finally执行顺序

    try和finally,没有catch可以吗?可以
        try不能单独使用
        try finally 可以联合使用
    以下代码的执行顺序:
        先执行try......
        再执行finally
        最后执行return  (return执行方法必然结束)

11.1代码展示

package com.power.javase.exception;
/*
finally语句:放在finally里面的代码是一定会执行的
 */
public class ExceptionTest11 {
    public static void main(String[] args) {
        try{
            System.out.println("try.........");
            return;
        }finally{                                   //就算try中有return语句,finally也会执行到
            //finally中的语句会执行,能执行到
            System.out.println("finally...........");
        }

        //这里不能写语句,因为这个代码是无法执行到的
        //System.out.println("hello world");
    }
}

11.2执行结果

在这里插入图片描述

12唯有 System.exit(0),finally语句不再执行

System.exit(0);只有这种情况下,退出JVM之后,finally语句中的代码不再执行

12.1代码展示

package com.power.javase.exception;
/*
fially
 */
public class ExceptionTest12 {
    public static void main(String[] args) {
        try{
            System.out.println("try...");
            //退出JVM
            System.exit(0);//退出JVM之后,finally语句中的代码就不执行了
        }finally{
            System.out.println("finally...");
        }
    }
}

12.2执行结果

在这里插入图片描述

13Finanlly面试题

13.1代码展示

package com.power.javase.exception;
/*
finally面试题
 */
public class ExceptionTest13 {
    public static void main(String[] args) {
        int result = m();
        System.out.println(result);
    }
    /*
    java语法规则(有一些规则是不能破坏的,一旦这么说来,就必须这么做)
        Java中有一条这样的规则:
            方法体中的代码必须遵循自上而下书匈奴以此逐行执行(恒古不变的语法)
         Java中还有一条语法规则:
            return语句一旦执行,整个方法必须结束(恒古不变的语法)
    */
    public static int m(){
        int i=100;
        try{
            //这行代码出现在int i = 100 的下面,所以最终解雇必须是返回100
            //return 语句还必须保证是最后执行的。一旦执行,整个方法结束
            return i;
        }finally{
            i++;
        }
    }
}

13.2反编译过程

可以看出,此时找了一个临时变量

反编译之后的效果   找了个临时变量
public static int m(){
    int i = 100;
    int j = i;
    i++;
    return j;
}

13.3执行结果

执行结果为100
在这里插入图片描述

14初始异常

fianl finally finalize 有什么区别?
final关键字
final修饰的类无法继承
final 修饰的方法无法覆盖
final 修饰的变量不能重新赋值
finally 关键字
和try联合使用
finally语句块中的代码时必须执行的

finalize 标识符
是一个Object类中的方法名
这个方法是由垃圾回收器GC负责调用的

14.1代码展示

package com.power.javase.exception;
/*
fianl finally finalize 有什么区别?
final关键字
    final修饰的类无法继承
    final 修饰的方法无法覆盖
    final 修饰的变量不能重新赋值
finally 关键字
    和try联合使用
    finally语句块中的代码时必须执行的

finalize 标识符
    是一个Object类中的方法名
    这个方法是由垃圾回收器GC负责调用的
 */
public class ExceptionTest14 {
    public static void main(String[] args) {
        //final是一个关键字,表示最终的,不可变的
        final int i = 100;

        //i = 200;

        //finally也是一个关键字,和try联合使用,使用在异常处理机制中
        //再finally语句块中的代码是一定会执行的
        try{

        }finally{
            System.out.println("finally.....");
        }

        //finalize()是Object类中的一个方法,作为方法名出现
        //所以finalize()是标识符
        Object object;
    }
}
//final 修饰的类无法继承
final class A{
    //常量
    public static final double PI=3.1415926;
}
class B{
    //final修饰的方法无法覆盖
    public final void doSome(){

    }
}

14.2执行结果

在这里插入图片描述

15怎么样自定义异常

15.1自定义异常方法

1、SUN提供的JDK内置的异常肯定是不够用的。在实际开发过程中,有很多业务,
这些业务踹你异常之后,JDK都是没有的。和业务挂钩的。那么异常我们
程序员可以自己编写吗?
可以。
2.Java中怎么自定义异常呢?
两步?
第一步:编写一个类继承Exception或者RuntimeException
第二部:提供两个构造方法,一个无参的,一个带有String参数
死记硬背。

15.2代码展示

以下两个代码块含义一样

public class MyException extends Exception{ //编译时异常
    public MyException(){
    }
    public MyException(String s){
        super(s);
    }
}
package com.power.javase.exception;
栈操作异常:自定义异常
 */
public class MyStackOperationException extends Exception{
    //无参构造
    public MyStackOperationException(){     //编译时异常
    }

    //有参构造
    public MyStackOperationException(String s){
        super(s);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值