本帖最后由 风中的消逝 于 2018-4-23 15:09 编辑
【石家庄校区】就业班_JavaSE_day08_异常 异常
* 概念: 是程序编译时期或者运行时期出现的错误。
* 异常的继承体系:
* java.lang.Throwable(最顶层的类)
* Error: 不应该试图捕获的异常 (OutOfMemoryError 内存溢出 StackOverflowError 递归太深而发生堆栈溢出) 不用程序员处理
* Exception: 可以处理的异常,除了运行时异常。(由程序的运行环境导致) 必须处理
* RuntimeException: 运行时异常 (程序代码问题导致) 看应用场景的情况。
例如:
队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。
在这个场景下, 捕获所有的运行时异常,不让程序终止。这样处理是一个捕获运行时异常比较好的应用。
但并不代表在所有的场景你都应该如此。如果在其它场景,遇到了一些错误,如果退出程序比较好,这时你就可以不太理会运行时异常。
注意:下面二种写法不建议。隐藏了异常。
public void getNum(int a, int b) {
if(b != 0 ) {
System.out.println( a/b);
}
}
public void getNum(int a, int b) {
try{
System.out.println( a/ b);
}catch(ArithmeticException e){
}
}
改进写法
public void getNum(int a, int b) {
System.out.println( a/b); //不处理运行时异常
}
或者
public void getNum(int a, int b) {
if(b == 0 ) {
throw new ArithmeticException("被零除"); //手动抛出异常
}
System.out.println( a/b);
}
public void getNum(int a, int b) {
try{
System.out.println( a/ b);
}catch(ArithmeticException e){
e.printStackTrace(); //加上处理的代码
}
}
* 异常的分类
*检查异常(Exception) 和非检查异常(Error 和 RuntimeException)
* 自定义异常
* 自定义编译时异常: 继承Exception类, 重写构造方法 参考JDK源码
* 自定义运行时异常: 继承RuntimeException, 重写构造方法 参考JDK源码
public class IOException extends Exception {
static final long serialVersionUID = 7818375828146090155L;
public IOException() {
super();
}
public IOException(String message) {
super(message);
}
public IOException(String message, Throwable cause) {
super(message, cause);
}
public IOException(Throwable cause) {
super(cause);
}
}
public class IllegalArgumentException extends RuntimeException {
private static final long serialVersionUID = -5365630128856068164L;
public IllegalArgumentException() {
super();
}
public IllegalArgumentException(String s) {
super(s);
}
public IllegalArgumentException(String message, Throwable cause) {
super(message, cause);
}
public IllegalArgumentException(Throwable cause) {
super(cause);
}
}
* 异常的处理方式
* JVM默认的异常处理方式
* 把异常信息打印到控制台, 终止程序的运行, 发生异常之后的代码都不会执行
* 手动处理异常的方式(2种)
* 捕获异常: `try catch`
* try catch格式(见下方)
* 多异常的处理
* catch代码块的顺序
* 如果多个异常没有继承关系, 顺序无所谓
* 如果多个异常有继承关系, 子类异常在上, 父类异常在下
* 捕获异常的执行逻辑
* 如果try代码块中发生异常, 则会从发生异常的代码直接跳转到catch语句中
* finally
* 是一个关键字, 与final区分
* 作用: 与try catch配合, 无论是否发生异常, 无论是否捕获异常, 都会执行finally代码块
* 应用:
* IO流释放资源时, 将close()方法放在finally代码块中
* 抛出异常: 交给调用者处理, `throws`
* `throws`:
* 定义在方法声明上
* 是处理异常的一种方式, 方法内部不处理, 由方法的调用者处理
* 格式: `方法声明 throws 异常类型1, 异常类型2 {}`
* `throw`
* 用在方法中
* 制造异常, 抛出一个异常对象
* 格式: `throw new 异常类型构造方法();`
* Throwable常用方法
* `String getMessage()`: 获取异常的原因, 没有原因则返回null
* `String toString()`: 返回异常的类型和原因
* `void printStackTrace()`: 使用标准错误输出流打印异常详情
面试题
public int getNum() {
try{
int i = 10/0;
return 1;
}catch (Exception e) {
return 2;
}finally {
return 3;
}
}
该方法的返回值是多少。返回3, 为什么返回3?
|