异常
1. 了解异常的概念
编写的程序是来源或超脱于现实生活的。
生活中 不符合你预期情况的场景 就是出现异常了!
程序中的异常:
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
System.out.println("感谢使用本程序!");
生活中不能放弃,程序中也不能放弃。
程序中的解决方案为:(代码臃肿,补足很困难!)
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
// hasNextXXX() 判断Scanner接收到的你输入的值 是否是某个类型 如果是为true
if(in.hasNextInt()) {
// 将类型进行转换
int num1 = in.nextInt();
System.out.print("请输入除数:");
if(in.hasNextInt()) {
int num2 = in.nextInt();
// 排除掉0为除数场景
if(num2 == 0) {
System.out.println("除数不能为0!");
}else {
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
}
}else {
System.out.println("对不起!除数必须为整数!");
}
}else {
System.out.println("对不起!被除数必须为整数!");
}
System.out.println("感谢使用本程序!");
异常:程序中出现了不正常情况,会导致程序中断!
2.理解Java异常处理机制
try 尝试 试图
catch 捕捉 抓住
finally 最终的 最后的
throw 抛出 扔
throws 抛出 扔 (Java编程网络释义:声明异常)
2.1 会捕捉异常(try-catch)
-
try-catch
// 可能有代码段 try{ // 可能会出现异常问题的代码 }catch(异常类型 形参名){ // 出现了异常 解决异常的代码 } // 可能有代码段
正常情况 与没加效果一致
出现了异常(声明了可以捕获) 当try块中的某一行代码出现了异常,那么try块中的后续代码将不再执行,直接会跳转到catch块中进行异常的处理,处理完之后继续向下执行。
出现了异常(异常类型不匹配) 当try块中的某一行代码出现了异常,那么try中的后续代码将不再执行,catch块中声明的异常类型不匹配,那么异常将不会被处理,会采用默认处理方式。(它就好像你没加过try-catch一样)
联想 缉毒警察解决不了防暴警察的活。
-
try-catch-catch
多重catch的情况(联想多重if)
特点 当出现异常时,会自上而下的进行判断,判断是否符合catch块中的异常,如果能符合,直接执行此catch块,后续的catch不会触发!
联想多重if记住 最容易匹配的 不要放在前方。 因为多态的原因,如果你将父类放在上方,下方的子类catch就不会执行了!
Scanner in = new Scanner(System.in); try { // 可能会出现问题的代码 System.out.print("请输入被除数:"); int num1 = in.nextInt(); System.out.print("请输入除数:"); int num2 = in.nextInt(); System.out.println(num1+"/"+ num2 +"="+ num1/ num2); }catch(InputMismatchException e) { // 出现了问题之后 如何解决 System.out.println("输入不匹配!必须输入整数!"); e.printStackTrace(); }catch(ArithmeticException e) { System.out.println("除数不能为0!"); System.err.println(e.getMessage()); }catch(Exception e) { System.out.println("有异常出现:"+e.getMessage()); } System.out.println("感谢使用本程序!");
3. try-catch-finally
特点 无论try块中代码是否有异常,都会执行finally块中的代码片段。
1.出现了退出虚拟机语句 : System.exit(0);
2.return关键字:结束当前方法,返回到方法的调用者处。 当try-catch中同时出现了return和finally块,它会先执行finally块中的代码,然后才执行return。
Scanner in = new Scanner(System.in);
try {
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
}catch(InputMismatchException e) {
System.out.println("输入不匹配!");
return;
}finally { // 无论是否出现异常 都会执行!
System.out.println("感谢使用本程序!");
}
注意事项:
try、catch 、finally可以随意组合,但是它们不能单独出现。
异常出现之后,究竟JVM在做什么事?
当异常出现之后,JVM中会帮你创建对应异常类型的对象(例如:new InputMismatchException(异常提示信息)),如果没有(能处理的)try-catch,采用默认将异常信息进行封装 然后在控制台打印。
异常的堆栈跟踪信息:(我们也可以通过异常对象的方法 printStackTrace()来输出异常的堆栈跟踪信息)
Exception in thread "main"(异常出现在哪个线程) java.lang.ArithmeticException(出现了什么类型的异常): / by zero(异常的缘由信息)
at cn.kgc.demo2.Demo1.main(Demo1.java:21) (异常出现的位置 具体到某个包下的某个类下的某个方法 类中的第几行)
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864) // 异常出现的根本位置
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at cn.kgc.demo2.Demo2.main(Demo2.java:10) // 异常出现的直接位置
如果有能够处理的try-catch块,那么JVM会将这个异常对象传给catch(异常类型 形参名)块,然后你就可以通过形参去查看异常相关信息或做对应异常处理了。
2.2 会抛出异常(throws throw)(JavaWeb部分会再次提到用法)
不处理 ->
之所以出现throw和throws的目的就是当某个位置出现异常之后,如果它不想处理就可以将此异常上抛,上抛给调用者。
后期的常用形式:为了借助finally块的特点,处理完最终执行内容之后,再将异常上抛。
throws:后面的接的是此方法可能出现的异常的类型 可以同时指定多个 逗号隔开
throw:用来抛出异常对象。
子类重写父类方法:
子类重写父类方法,这个方法不能抛出比父类更多的异常,也不能抛出更大的异常。
3. 了解Java异常体系结构(类的家族树)
Throwable
Error Exception
**Error:**程序无法通过代码来修复!必须人工干预解决。 OutOfMemoryError 内存溢出 StackOverflowError 堆栈溢出等 编译错误(语法错误)等
**Exception:**程序执行过程中,可能会出现一些问题,可以提前做好处理工作。
**RuntimException:**运行时异常 例如:InputMismatchException ArrayIndexOutOfBoundsEception NullPointerException ClassCastException 运行期间 可能会出现这些错误!
**checked异常:**受检异常/检查异常 例如:FileNotFoundException ClassNotFoundException Java程序中人家认为这种异常很可能出现,所以必须要提前解决!增强程序的健壮性!
自定义异常:
/**
* 自定义异常(异常种类更加丰富 更加具体)
* @author Charles7c
* 2019年2月18日 上午11:51:42
*/
public class IllegalAgeException extends RuntimeException{
public IllegalAgeException(String message) {
super(message);
}
public IllegalAgeException() {
}
}
4. (目前作为了解) 异常记录 - 日志(log4j)
日志:(记录东西) 在程序运行期间 记录程序的状态 、用户操作行为、异常情况的一种东西。
log
日志是为了以后我们分析程序运行情况和解决问题的根据!重要!
日志记录工具/框架:log4j(log for java) logback
- 下载jar包(人家编写的代码的字节码压缩包)
- 将Jar包引入到你的工程内(先建立一个lib文件夹,将jar包放进去,右键jar包进行build path)
- 像使用JRE内的类库一样去使用它即可。
info(); 记录普通信息的
error(); 记录错误信息的
debug(); 可以用来记录一下特别的普通信息的
至于log4j配置文件的编写工作,可以自行查看提供的注释和文档。