Throwable类中3个异常处理的方法与finally代码块

Throwable类中3个异常处理的方法

  

package Demo_Exception;

import java.io.IOException;

/*
try...catch:异常处理的第二种方式,自己处理异常
格式:
try{
    可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中抛出的异常对象){
    异常的处理逻辑,异常异常对象之后,怎么处理异常对象
    一般在工作中,会把异常的信息记录到一个日志中
}
...
catch (异常类名 变量名){
    }
注意:
        1.try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
        2.如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try ...catch之后的代码
        如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try...catch之后的代码
 */
public class Demo04TryCatch {
    public static void main(String[] args) {
        try {
            readFile("d:\\a.txt");
        } catch (IOException e) {//try中抛出什么异常对象, catch就定义什么异常变量,用来接收这个异常对象
            //异常的处理逻辑,异常异常对象之后,怎么处理异常对象
//            System.out.println("catch - 传递的文件后缀不是.txt");
            /*
            ThrowabLe类中定义了3个异常处理的方法
            String getMessage()返回此throwable的简短描述。String tostring()返回此throwable 的详细消息字符串。
            void printstackTrace()”JVI打印异常对象,黑默认此方法,打印的异常信息是最全面的
             */
           // System.out.println(e.getMessage()); //文件的后缀不对
            // system.out.println(e.getMessage());//文件的后缀名不对
            //system.out.printLn(e.toString());//重写object类的tostring java.io.IOException:文件的后缀名不对
            //system.out.println(e);/ /java.io.IOException:文件的后缀名不对
            e.printStackTrace();
        }
        System.out.println("后续代码");
    }
        //如果传递的路径,不是.txt结尾
    //那么我们就抛出Io异常对象,告知方法的调用者,文件的后缀名不对

    public static void readFile(String fileName) throws IOException {
        if (!fileName.endsWith(".txt")){
            throw  new IOException("文件的后缀不对");
        }
        System.out.println("路径没有问题,读取文件");
    }
}

(1)Error

内存不足,硬盘损坏等问题
举例:
内存溢出错误-OutOfMemoryError
如图所示写了个死循环,一直做字符串拼接,Java程序就会报错,提示内存溢出

 

 

(2)Exception

 

分为:运行时异常(RunTimeException)、非运行时异常

运行时异常举例:

1.算术错误异常-ArithmeticException

0不能作为被除数,不运行时程序逻辑语法是没有问题的,所以不会报错,但运行之后就会报错,提示ArithmeticException,这是Java中

自带的异常分类,即告诉我们,出现的异常属于算术错误问题

 

 

异常处理try-catch

以上面的例子为例,选择第二种解决方案,使用【try-catch】语法进行异常处理,程序不再报错,如图所示:

 

 

finally代码块

finally代码块:

必须执行的代码块,不管是否有异常产生,即使发生OutOfMemoryError也会执行,通常用于执行善后清理工作。如果finally代码块没有执行,那么有三种情况可能:

1、没有进入try代码块。

2、进入try代码块,但是代码运行中出现了死循环或死锁情况。

3、进入try代码块,但是执行了System.exit()操作。

注意,finally是在return表达式运行后执行的,此时将要return的结果已经暂存起来,待finally代码块执行结束后再将之前暂存的结果返回,

 

package Demo_Exception;

public class Demo06_finally {
    public static void main(String[] args) {
        int result = finallyNotWork();
        System.out.println(result);// 10001
    }
    public static int finallyNotWork() {
        int temp = 10000;
        try {
            throw new Exception();
        } catch (Exception e) {
            return ++temp;
        } finally {
            temp = 99990;
        }
    }

}

 

finally代码块的职责不在于对变量进行赋值等操作,而是清理资源、释放连接、关闭管道流等操作。
相对在finally代码块中赋值,更加危险的做法是在finally块中使用return操作,这样的代码会使返回值变得非常不可控,警示代码如下:

public class TryCatchFinally {
  static int x = 1;
  static int y = 10;
  static int z = 100;
  public static void main(String[] args) {
    int value = finallyReturn();
    System.out.println("value=" + value);
    System.out.println("x=" + x);
    System.out.println("y=" + y);
    System.out.println("z=" + z);
  }
  private static int finallyReturn() {
    try {
       // ...
       return ++x;
    } catch (Exception e) {
       return ++y;
    } finally {
       return ++z;
    }
  }
}

以上执行结果说明:

1、最后return动作是由finally代码块中的return ++z完成的,所以方法返回的结果是101。

2、语句return ++x中的++x被成功的执行,所以运行结果是x=2。

3、如果有异常抛出,那么运行结果将会是y=11,而x=1。

finally代码块中使用return语句,使返回值的判断变得复杂,所以避免返回值不可控,我们不要在finally代码块中使用return语句。

Class Test{
    public static String output="";
    public static void foo(int i){
        try{
            if(i==1){
                throw new Exception();
            }
            output+="1";
        } catch(Exception e){
            output+="2";
            return;
        }  finally{
            output+="3";
        }
        output+="4";
    }
    public static void main(String args[]){
        foo(0);
        System.out.println(output);//134
        foo(1);
        System.out.println(output);//13423
    }
}

 

 

 

 

 

 

package Demo_Exception;

import java.io.IOException;

/*
try...catch:异常处理的第二种方式,自己处理异常
格式:
try{
可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中抛出的异常对象){
异常的处理逻辑,异常异常对象之后,怎么处理异常对象
一般在工作中,会把异常的信息记录到一个日志中
}
...
catch (异常类名 变量名){
}
注意:
1.try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
2.如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try ...catch之后的代码
如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try...catch之后的代码
*/
public class Demo04TryCatch {
public static void main(String[] args) {
try {
readFile("d:\\a.txt");
} catch (IOException e) {//try中抛出什么异常对象, catch就定义什么异常变量,用来接收这个异常对象
//异常的处理逻辑,异常异常对象之后,怎么处理异常对象
// System.out.println("catch - 传递的文件后缀不是.txt");
/*
ThrowabLe类中定义了3个异常处理的方法
String getMessage()返回此throwable的简短描述。String tostring()返回此throwable 的详细消息字符串。
void printstackTrace()”JVI打印异常对象,黑默认此方法,打印的异常信息是最全面的
*/
// System.out.println(e.getMessage()); //文件的后缀不对
// system.out.println(e.getMessage());//文件的后缀名不对
//system.out.printLn(e.toString());//重写object类的tostring java.io.IOException:文件的后缀名不对
//system.out.println(e);/ /java.io.IOException:文件的后缀名不对
e.printStackTrace();
}
System.out.println("后续代码");
}
//如果传递的路径,不是.txt结尾
//那么我们就抛出Io异常对象,告知方法的调用者,文件的后缀名不对

public static void readFile(String fileName) throws IOException {
if (!fileName.endsWith(".txt")){
throw new IOException("文件的后缀不对");
}
System.out.println("路径没有问题,读取文件");
}
}

posted @ 2022-07-07 14:30  zj勇敢飞,xx永相随  阅读(81)  评论(0编辑  收藏  举报