day0609异常
-
一次编译,随处运行JVM机制
-
面向对象
-
安全(内存申请 内存释放),GC(garbage collection)回收机制
-
栈帧,一个方法一个,方法结束就回收
-
堆内空间gc回收,定期检查堆内对象是否无人使用
-
-
健壮性:异常机制
异常体现
-
程序中的不正常事件:错误(Error)和异常(Exception)
-
错误,要么改机器配置,要么更改源码
-
Throwable是Error和Exception的父类
Error是所有的错误的父类
Exception是所有的异常的父类
一类是运行时异常/非受检异常(是RuntimeException的子类):不处理,编译可过
一类是编译时异常/受检异常(不是):必须处理,编译过不了
运行时异常
异常类型 | 说明 |
---|---|
ArithmeticException | 算术错误异常,如以零做除数 |
ArraylndexOutOfBoundException | 数组索引越界 |
ArrayStoreException | 向类型不兼容的数组元素赋值 |
ClassCastException | 类型转换异常 |
IllegalArgumentException | 使用非法实参调用方法 |
lIIegalStateException | 环境或应用程序处于不正确的状态 |
lIIegalThreadStateException | 被请求的操作与当前线程状态不兼容 |
IndexOutOfBoundsException | 某种类型的索引越界 |
NullPointerException | 尝试访问 null 对象成员,空指针异常 |
NegativeArraySizeException | 再负数范围内创建的数组 |
NumberFormatException | 数字转化格式异常,比如字符串到 float 型数字的转换无效 |
TypeNotPresentException | 类型未找到 |
非运行时异常
异常类型 | 说明 |
---|---|
ClassNotFoundException | 没有找到类 |
IllegalAccessException | 访问类被拒绝 |
InstantiationException | 试图创建抽象类或接口的对象 |
InterruptedException | 线程被另一个线程中断 |
NoSuchFieldException | 请求的域不存在 |
NoSuchMethodException | 请求的方法不存在 |
ReflectiveOperationException | 与反射有关的异常的超类 |
异常处理
-
try,异常类型(其父类都可以)匹配才可以抓住
这里可以理解为父类引用指向子类对象
形参是记录了对象,jvm new的异常的对象,异常也是对象
出现异常后,直接跳出try块,后续语句不执行
try{ //有可能出现异常的代码 }catch(异常类型 形参){ //对异常的处理 } e.getMessage Exception类的方法之一获取堆栈报错信息 e.printStackTrance();
getMessage() 方法: Exception类的方法之一, 返回异常的原因, 上面的 / by zero 就是这个方法输出的.
printStackTrace(): Exception类的方法之一, 在屏幕输出函数栈信息, 也就是异常出现的地方.
-
多重catch
如何确定异常类型?
经验或者跑一下
Exception,父类引用指向子类对象
看函数定义的throws后缀
小类型在上,大类型在下
try{ }catch(){ }catch(){ }
-
finally
-
无论抓不抓得到都会执行
-
即使catch中有return,finally的语句在编译时会被提前到return之前。只有断电或者exit函数才会阻止其运行
-
哪些代码必须执行?资源释放
try{ }catch(){ }catch(){ }finally{ } //没抓住,这里不执行
-
抛异常
-
运行时异常,可以认为是JVM自动创建new了,自动的抛给上层调用者
-
编译时异常,需要自行new出异常,并且抛出或者处理掉
throw new NullPointerException();
-
throw用在方法内部,后面是异常对象,表示把异常抛出
-
throw new XException();
-
效果等价于return,表示方法结束,后续代码不再执行
-
-
throws,用在方法声明处,表示此方法会抛出的异常
-
方法名 throws (受检)异常名,异常名{}
-
public void f() throws Exception1, Exception2…{}
-
如果一个方法里利用throw手动抛出1个非RuntimeException异常, 必须在函数定义声明里加上throws 后缀
-
throw和throws区别
-
throw 写在函数体内, throws写在函数定义语句中.
-
throw 是抛出1个异常对象, throws是有能抛出异常的种类
所以throw后面的一般加上new 和exception名字().
而throws后面不能加上new的
-
一个方法最多只能throw1个异常, 但是可以throws多个种类异常
因为一旦一个函数throw出1个异常, 这个函数就会被中断执行, 后面的代码被放弃, 如果你尝试在函数内写两个throw, 编译失败.
而throws 是告诉别人这个函数有可能抛出这几种异常的一种. 但是最多只会抛出一种.
-
如果在一个函数体内throw 1个非runtimeException, 那么必须在函数定义上加上throws后缀. 但反过来就不是必须的.
自定义异常
可以继承 和一般的类区别不大
编写一个类继承一个异常类
可以见到c语言处理错误有这些特点
- 大部分精力都在错误处理.
2. 需要把各种可能出现的错误全部考虑到, 才能保证程序的稳定性.
-
程序可读性差, 错误处理代码混杂在其他代码中.
-
出错返回信息少, 一旦出错难以调试.
-
一旦出现了未考虑到的错误, 资源释放代码无法执行.
8.3 java异常机制的优点:
-
业务代码和错误处理代码分离.
-
强制程序猿考虑程序的稳定性.
-
有利于代码调试(异常信息)
-
即使任何异常产生, 能保证占用的释放(finally)
8.4 java异常机制的缺点:
-
异常嵌套难免影响代码可读性
-
并不能令程序逻辑更加清晰.
-
异常并不能解决所有问题