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("路径没有问题,读取文件");
}
}