Java深入学习——异常
异常是程序在“编译”或者“执行”的过程中可能出现的问题
异常一旦出现了,如果没有提前处理,程序就会退出JVM虚拟机而止,开发过程中是需要提前处理的
Java通常会为代码异常设计一个类来代表。
Java的异常体系
Java中的异常继承的根类是:Throwable
Error:错误的意思,严重错误Error,无法通过处理的错误,一旦出现,程序员也无能为力,只能重启系统,优化项目,比如内存崩溃,JVM本身的崩溃,这个程序员无需理会
Exception:才是异常类,他才是开发中代码在编译或者执行的过程中可能出现的,他需要提前处理,以便程序更加健壮
编译时异常:继承自Exception的异常或者其子类,编译阶段就会报错,必须程序员处理的,否则代码编译就不能通过
运行时异常:继承自RuntimeException的异常或者其子类,编译阶段时不会出错的,他是在运行阶段可能出现,运行时异常可以处理也可以不处理,编译阶段是不会出错的,但是运行阶段可能出现,还是建议提前处理
异常的产生默认的处理过程解析(自动处理的过程):
- 默认会在出现异常的代码那里自动创建一个异常对象:
ArithmeticException
- 异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机
- 虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据
- 直接从当前执行的异常点结束当前程序
- 后续代码没有机会执行,因为程序已经死亡
编译时异常的处理机制
-
抛出异常
格式:
方法 throws 异常1,异常2, ...{ }
出现异常的地方层层抛出,谁都不处理,最终抛给虚拟机,这种方式虽然可以解决编译时异常,但是如果异常真的出现了,程序会直接死亡
如果异常写Exception,那么就可以抛出一切异常,因为Exception是编译时异常的共同父类
-
捕获异常
自己捕获和处理异常的格式:
try{ //监视可能出现异常的代码 }catch(异常类型1 变量){ //处理异常 }catch(异常类型2 变量){ //处理异常
同理这里的异常类型也可以写Exception,捕获一切异常
trycatch方法,如果出现异常,捕获异常后继续执行下一步的代码,程序不会终止
eg:
@Test public void test1(){ System.out.println("程序开始"); try { parseDate("2013-03-23 10:19-df"); System.out.println("lll"); } catch (Exception e) { System.out.println("aaa"); e.printStackTrace(); } System.out.println("bbb"); }
执行结果
-
在出现异常的地方把异常一层一层的抛出给最外层调用者,最外层调用者集中捕获处理(规范的写法)
public class ExceptionDemo1 { public static void main(String[] args) { try { System.out.println("程序开始"); parseDate("2013-03-23 10:19:23"); System.out.println("成功执行"); } catch (Exception e) { e.printStackTrace(); System.out.println("出现异常"); } System.out.println("程序结束"); } public static void parseDate(String time) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = sdf.parse(time); System.out.println(d); InputStream is = new FileInputStream("C:/sml.txt"); }
运行截图:
运行时异常的处理机制
运行时异常是自动往外抛的(默认throws RuntimeException
)不需要我们手工抛出。
运行时异常的处理规范,直接在最外层捕获处理即可
finally关键字
用于捕获处理的异常格式中的,放在最后面,用于在代码执行完毕后进行资源的回收操作
try{
// 可能出现异常的代码
}catch(Exception e){
e.printStackTrace;
}finally{
//无论代码是出现异常还是正常执行,最终一定要执行这里的代码
}
自定义异常
自定义编译时异常:
- 定义一个异常类继承Exception
- 重写构造器
- 在出现异常的地方用throw new 自定义异常抛出
自定义运行时异常:
- 定义一个异常类继承RuntimeException
- 重写构造器
- 在出现异常的地方用throw new 自定义异常抛出
eg:
public static void main(String[] args) {
try {
checkAge(300);
} catch (AgeIllegal ageIllegal) {
ageIllegal.printStackTrace();
}
}
public static void checkAge(int age) throws AgeIllegal {
if (age > 200 || age < 0){
throw new AgeIllegal("/age is illegal!");
}
}
/*********************************/
/**
* @author YJL
*/
public class AgeIllegal extends Exception{
public AgeIllegal() {
}
public AgeIllegal(String message) {
super(message);
}
public AgeIllegal(String message, Throwable cause) {
super(message, cause);
}
public AgeIllegal(Throwable cause) {
super(cause);
}
public AgeIllegal(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}