欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

大数据DAY21——IO流(异常)

时间:2023-04-17

目录

异常

异常概述

异常分类

编译时异常和运行时异常的区别

异常案例

JVM的默认处理方案:

异常处理:try…catch…finally方法

try...catch...finally处理方式:

变形格式:

处理多个异常

JDK7后出现的多个异常方法:

Throwable中的方法

throws处理异常

throws案例

throw处理异常

throws和throw的区别

throws

throw

如何去选择处理异常的方法

finally的特点作用

finally的特点

finally的作用

异常注意事项


异常

异常概述

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

异常由来:问题也是现实生活中一个具体事务,也可以通过java 的类的形式进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。

如,数组下标越界异常,空指针异常

异常分类

A.严重问题:Error是严重的问题,我们不处理,如内存溢出(OOM)

B.问题:Exception(异常)

编译时异常和运行时异常的区别

1.编译时期异常:除了RuntimeException都是编译时期异常,必须处理,不然无法通过编译运行。

2.运行时期异常:RuntimeException类及其子类,一般情况下,不会对问题本身处理,因为问题是在写代码的过程中由于逻辑不严谨导致的。

异常案例

例:除数为0

public class ExceptionTest1 { public static void main(String[] args) { int a=120; int b=0; System.out.println(a/b); //除数不能为0 System.out.println(a); }}

因为0不能作为除数,所以a/b会报错,也就是异常,后面的代码也不会继续执行

 

 如果我们不做出任何处理,JVM会默认处理

JVM的默认处理方案:

把异常的名称,错误原因及异常出现的位置等信息输出在了控制台 ,程序停止执行

异常处理:try…catch…finally方法

try...catch...finally处理方式:

try{

可能出现问题的代码

}catch(异常名  变量名){

针对出现问题后的处理代码

}finally{

只要是程序顺利执行,finally里面的内容无论如何都会执行

}

变形格式:

try{

可能出现问题的代码

}catch(异常名  变量名){

针对出现问题后的处理代码

}

继续0不能作为除数的例子

public class ExceptionTest1 { public static void main(String[] args) { int a=120; int b=0; try{ System.out.println(a/b); }catch (ArithmeticException o){ System.out.println("除数为0"); } System.out.println(a); }}

 经过try...catch处理后,输出了处理的方法,也能继续执行后面的代码

处理多个异常

如果有多个异常需要处理,要么每一个异常写一个try...catch,要么写一个try多个catch:

try{

可能出现问题的代码

}catch(异常名1  变量名1){

针对出现异常1后的处理代码

}catch(异常名2 变量名2){

针对出现异常2后的处理代码

}...

注意1:当使用一个try多个catch的方法时,catch只能匹配对应的异常,并且只能匹配一个异常

例:

public class ExceptionTest2 { public static void main(String[] args) { int c=111; int d=0; int []arr ={1,2}; try{ System.out.println(c/d); //这里异常,try中的语句就不会走了,直接去匹配异常了 System.out.println(arr[2]); //数组下标越界 }catch(ArithmeticException o){ System.out.println("除数为0"); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("数组下标越界"); } }}

 当把d修改为不为0的数(如:3),才会去走try中下一个语句,再去匹配相应异常

注意2:catch中平级关系的异常顺序无所谓,如果出现了父子继承关系,父类异常要放在最后,不然会直接去匹配父类导致错误

所以catch中的异常类型尽量明确,否则有多个异常处理方式都一样

JDK7后出现的多个异常方法:

try{

可能出现问题的代码

}catch(异常1 |  异常2 | ...){

处理方法

}

这种方法虽然简洁,但多种异常用一种方法处理,需谨慎使用,catch里也只能写平级关系异常。

Throwable中的方法

getMessage()  获取异常信息,返回字符串

import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class Test2 { public static void main(String[] args) { //日期转换 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String s="2022-12-29 21:26"; //正确写法:2022-12-29 21:26:23 try{ Date parse = simpleDateFormat.parse(s); System.out.println(parse); } catch (ParseException e) { System.out.println(e.getMessage()); //获取异常信息 } }}

当输入的日期格式正确时,输出就是我们想要的日期

当输入的日期格式不正确时,就会获取异常信息

 

toString() 获取异常类名和异常信息,返回字符串

System.out.println(e.toString());

printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void

e.printStackTrace();

 跟我们不做处理的效果差不多,唯一不同就是你处理了这个异常,后面代码可以继续执行,这是最好的方法。

throws处理异常

 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。

throws案例

当没有限权去处理异常时,又不能不去处理,否则后面的代码不能执行,所以java给出了解决方法:throws  抛出

语句格式:thows 异常类名

以日期转换为例(编译时期异常):

import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class ThrowsTest1 { public static void main(String[] args) { try { fun(); //调用日期转换的方法 } catch (ParseException e) { e.printStackTrace(); } System.out.println("处理完了"); } public static void fun() throws ParseException { //抛出异常 (先抛。抛给调用者) String s="2022-12-29 21:26"; //正确写法:2022-12-29 21:26:23 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date parse = simpleDateFormat.parse(s); System.out.println(parse); }}

 可以看出当方法里有异常可以抛给调用者,在调用的时候处理异常,后面的代码也能执行,否则程序报错,不能继续执行(如果调用者继续抛出,抛给JVM,也会报错,不能执行后面的代码)

所以尽量不要在main方法上抛出

再以0为除数为例(运行时异常):

public class ThrowsTest2 { public static void main(String[] args) { try{ fun(); } catch (ArithmeticException e) { e.printStackTrace(); } System.out.println("执行完了"); } public static void fun()throws ArithmeticException{ int a=10; int b=0; System.out.println(a/b); }}

throw处理异常

在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

public class ThrowTest1 { public static void main(String[] args) { fun(); System.out.println("执行完毕"); } public static void fun(){ int a=100; int b=0; if (b==0){ System.out.println("不能为除数"); //这里想表示的是b等于0,那么a/b就肯定会发生异常 throw new ArithmeticException(); //抛出一个异常对象 }else{ System.out.println(a/b); } }}

 虽然抛出了异常对象,但调用方法后的代码没有继续执行,所以在调用时也要处理

try{ fun(); } catch (ArithmeticException e) { e.printStackTrace(); }

处理了之后,调用方法后的代码就能正常执行

 

throws和throw的区别

throws

用在方法声明后面,跟的是异常类名

可以跟多个异常类名,用逗号隔开

表示抛出异常,由该方法的调用者来处理

throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

用在方法体内,跟的是异常对象名

只能抛出一个异常对象名

表示抛出异常,由方法体内的语句处理

throw则是抛出了异常,执行throw则一定抛出了某种异常  

如何去选择处理异常的方法

原则:

如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这时用throws

区别:

后续程序需要继续运行就try

后续程序不需要继续运行就throws

finally的特点作用

finally的特点

被finally控制的语句体一定会执行

特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))

例:

import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class FinallyTest1 { public static void main(String[] args) { String s="2022-12-29 21:26"; //正确写法:2022-12-29 21:26:23 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date =null; try{ date = simpleDateFormat.parse(s); } catch (ParseException e) { e.printStackTrace(); }finally { System.out.println("这里一定会执行"); } System.out.println(date); }}

 

 不管时间格式正不正确,finally里面的代码一定会运行,除非执行finally之前程序停止。

finally的作用

用于释放资源,在IO流操作和数据库操作中会见到

异常注意事项

a.子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

b.如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

c.如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。