点击上方 "程序员小乐"关注, 星标或置顶一起成长
每天凌晨00点00分, 第一时间与你相约
每日英文
A single hand that wipes tears during failures is much better than countless hands that come together to clap on success.
失败时有人伸出一只手来为你擦泪,会好过成功时无数人伸手为你鼓掌。
每日掏心话
当看破一切的时候才知道,其实失去比拥有更踏实。
来自:RealBruce | 责编:乐乐
链接:my.oschina.net/u/4001573/blog/3218016
往日回顾:Google 出品的 Java 编码规范,强烈推荐,权威又科学!
正文
异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)
Java程序在执行过程中所发生的异常事件可分为两类:
Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。
Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:
空指针访问
试图读取不存在的文件
网络连接中断
数组角标越界
异常的体系结构 * java.lang.Throwable * |-----java.lang.Error:一般不编写针对性的代码进行处理。 * |-----java.lang.Exception:可以进行异常的处理 * |------编译时异常(checked)不会生成字节码文件 * |-----IOException * |-----FileNotFoundException * |-----ClassNotFoundException * |------运行时异常(unchecked,RuntimeException) * |-----NullPointerException//空指针异常 * |-----ArrayIndexOutOfBoundsException//数组角标越界 * |-----ClassCastException//类型转化异常 * |-----NumberFormatException//编码格式异常 * |-----InputMismatchException//输入不匹配 * |-----ArithmeticException//算术异常
java中异常类的继承关系
运行时异常:执行javac.exe命名时,可能出现的异常 是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java. lang. Runtime Exception类及它的子类都是运行时异常。对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响
编译时异常:执行java.exe命名时,出现的异常 是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求Java程序==必须捕获或声明所有编译时异常== 对于这类异常,如果程序不处理,可能会带来意想不到的结果。
//******************以下是运行时异常*************************** //ArithmeticException @Test public void test6(){ int a = 10; int b = 0; System.out.println(a / b); } //InputMismatchException @Test public void test5(){ Scanner scanner = new Scanner(System.in); int score = scanner.nextInt(); System.out.println(score); scanner.close(); } //NumberFormatException @Test public void test4(){ String str = "123"; str = "abc"; int num = Integer.parseInt(str); } //ClassCastException @Test public void test3(){ Object obj = new Date(); String str = (String)obj; } //IndexOutOfBoundsException @Test public void test2(){ //ArrayIndexOutOfBoundsException// int[] arr = new int[10];// System.out.println(arr[10]); //StringIndexOutOfBoundsException String str = "abc"; System.out.println(str.charAt(3)); } //NullPointerException @Test public void test1(){ // int[] arr = null;// System.out.println(arr[3]); String str = "abc"; str = null; System.out.println(str.charAt(0)); } //******************以下是编译时异常*************************** @Test public void test7(){// File file = new File("hello.txt");// FileInputStream fis = new FileInputStream(file);// // int data = fis.read();// while(data != -1){// System.out.print((char)data);// data = fis.read();// }// // fis.close(); }
过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。并将此对象抛出。一旦抛出对象以后,其后的代码就不再执行。
关于异常对象的产生:
① 系统自动生成的异常对象
② 手动的生成一个异常对象,并抛出(throw)
过程二:"抓":可以理解为异常的处理方式:① try-catch-finally ② throws
try{ //可能出现异常的代码 }catch(异常类型1 变量名1){ //处理异常的方式1}catch(异常类型2 变量名2){ //处理异常的方式2}catch(异常类型3 变量名3){ //处理异常的方式3} ....finally{ //一定会执行的代码}
说明:
finally是可选的。
使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配
一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的try-catch结构(在没写finally的情况。继续执行其后的代码)
catch中的异常类型如果没子父类关系,则谁声明在上,谁声明在下无所谓。
catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错
常用的异常对象处理的方式:① String getMessage() ② printStackTrace()
在try结构中声明的变量,再出了try结构以后,就不能再被调用
try-catch-finally结构可以嵌套
如何看待代码中的编译时异常和运行时异常?
使用try-catch-finally处理编译时异常,是得程序在编译时就不再报错,但是运行时仍可能报错。相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。==针对于编译时异常,我们说一定要考虑异常的处理==。
finally是可选的
finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中return语句,catch中return语句等情况。
像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的释放。此时的资源释放,就需要声明在finally中。
"throws + 异常类型"==写在方法的声明处==。指明此方法执行时,可能会抛出的异常类型。一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后续的代码,就不再执行!
try-catch-finally:真正的将异常给处理掉了。throws的方式只是将异常抛给了方法的调用者。==并没真正将异常处理掉==。
如果父类中被重写的方法没throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中异常,必须使用try-catch-finally方式处理。
执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
补充:方法重写的规则之一:子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
在程序执行中,除了自动抛出异常对象的情况之外,我们还可以手动的throw一个异常类的对象。
throw 和 throws区别:throw 表示抛出一个异常类的对象,生成异常对象的过程。声明在方法体内。throws 属于异常处理的一种方式,声明在方法的声明处。
class Student{ private int id; public void regist(int id) throws Exception { if(id > 0){ this.id = id; }else{ //手动抛出异常对象// throw new RuntimeException("您输入的数据非法!");// throw new Exception("您输入的数据非法!"); throw new MyException("不能输入负数"); } } @Override public String toString() { return "Student [id=" + id + "]"; } }
继承于现的异常结构:RuntimeException 、Exception
提供全局常量:serialVersionUID(对类的唯一标识)
提供重载的构造器
public class MyException extends Exception{ static final long serialVersionUID = -7034897193246939L; public MyException(){ } public MyException(String msg){ super(msg); }}
欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。
欢迎各位读者加入订阅号程序员小乐技术群,在后台回复“加群”或者“学习”即可。
猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
如何更好的使用Java异常,看这篇就对了!
Java IO使用的四种模式
(三)SpringBoot+SpringCloud —— 高可用的Eureka注册中心
文章有问题?点此查看未经处理的缓存