异常
一、异常
1.定义:在程序运行的过程中出现的错误称为异常。
2.分类:
编译错误:又称为语法错误,不能运行,在编译阶段就报错。
int num ="100"; //编译错误,数据类型不一致。
运行错误:能正常编译,但是运行的时候发生错误。
int [] num= {1,2,3};
System.out.println(num[4]); //运行错误,数组下标越界。
逻辑错误:与预期的结果不一样,能正常编译和正常运行。
二、异常处理
1.实现方式:Java的异常是通过五个关键字来实现的:try、catch、finally、throw和throws。
2.处理异常的手段:try…catch…finally和throw…throws
三、try…catch…finally
- Ⅰ、try:监控代码,监控可能发生错误的代码。
①如果try里面的代码没有发生异常,则整个try执行完毕,不会进入catch,最后执行finally。
②如果try里面的代码发生异常,则try里面后面的代码不会执行,如果有对应的catch一定会进入catch(catch可以有多个),最后执行finally。
Ⅱ、catch:捕获catch里面指定类的异常。
①语法:catch(异常类 对象名){}
②catch可以有多个
注意:子类必须在父类的前面,不能出现相同的异常类。
结果:只会执行一个,第一次匹配的执行。
Ⅲ、finally:特点:不管是否发生异常,finally中的代码一定会被执行。
除非:①如果遇到了System.exit(1);不会执行finally直接退出程序。
②finally里面的代码也出现异常。
③程序死亡。
④CPU终止。
注意:try是必须存在的,catch和finally二选其一。
2.异常对象的常用方法
①void printStackTrace(); 输出异常的堆栈信息,堆栈信息包括程序运行到当前类的执行流程,它将输出从方法调用处到异常抛出处的方法调用序列。
②String getMessage(); 返回异常信息描述字符串,是printStackTrace()方法输出信息的一部分。
3.常见的异常类型
异常 | 说明 |
---|---|
Exception | 异常层次结构的根类 |
ArithmeticException | 算术错误情形,如以零作除数 |
ArrayIndexOfOutBoundsException | 数组下标越界 |
NullPointException | 空指针异常 |
ClassNotFoundException | 不能加载所需的类 |
InputMismatchException | 欲得到的数据类型与实际输入的类型不匹配 |
IllegalArgumentException | 方法接收到非法参数 |
NumberFormatException | 数字格式转换异常,如把"abc"转换成数字 |
StringIndexOfOutBoundsException | 字符串下标越界 |
FileNotFoundException | 文件找不到 |
ClassCastException | 对象强制类型转换出错 |
//try...catch块
Scanner in =new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int num1=in.nextInt();
System.out.println("请输入除数:");
int num2=in.nextInt();
System.out.println(String.format("%d / %d =%d", num1,num2,num1/num2));
System.out.println("感谢使用本程序!");
} catch (Exception e) {
System.err.println("出现错误:被除数和除数必须是整数,"+"除数不能为0");
e.printStackTrace();
}
//try...finally块
Scanner in =new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int num1=in.nextInt();
System.out.println("请输入除数:");
int num2=in.nextInt();
System.out.println(String.format("%d / %d =%d", num1,num2,num1/num2));
} finally
System.out.println("感谢使用本程序!");
}
//try...catch...finally块
Scanner in =new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int num1=in.nextInt();
System.out.println("请输入除数:");
int num2=in.nextInt();
System.out.println(String.format("%d / %d =%d", num1,num2,num1/num2));
} catch (Exception e) {
System.err.println("出现错误:被除数和除数必须是整数,"+"除数不能为0");
e.printStackTrace();
}finally
System.out.println("感谢使用本程序!");
}
四、throw…throws
为什么使用throw…throws?
如果问题你自己解决不了,可以寻求外援。
Ⅰ、throw:抛出异常,①有错误自己解决不了
位置:方法里面
语法:throw 异常对象名;
Ⅱ、throws:声明异常,②请求外援的动作
位置:方法名小括号后面
语法:throws 类名;
public class TestThrow{
public void method() throws Exception{ //声明异常
Exception e = new Exception("自定义异常信息");
throw e; //抛出异常
}
}
注意:调用的方法一旦声明了异常,那么外援一定要处理异常,如果没有处理,则编译报错。
TestThrow test = new TestThrow();
try {
test.method();
} catch (Exception e) {
System.out.println("外援在处理异常:" + e.getMessage());
}
区别:
作用不同:throw用于在程序中抛出异常;throws 用于声明在该方法内抛出了异常。
使用的位置不同:throw位于方法体内部,可以作为单独语句使用;throws 必须跟在方法参数列表的后面,不能单独使用。
内容不同:throw抛出一个异常对象,而且只能是一个;throws 后面跟异常类,而且可以跟多个异常类,用逗号隔开。
五、异常的分类
Throwable类:是所有异常类型的父类。
Error类:是Throwable类的子类,指程序本身无法修复的错误,比如虚拟机错误、内存溢出动态链接失败等,发生了这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。
Exception类:是Throwable类的子类,指程序本身会抛出的错误,我们可以解决的错误。
运行时异常:包括RunTimeException及其所有子类,如果运行时发生异常,会输出异常的堆栈信息并终止程序运行。
非运行时异常:CheckedException是编译错误,我们可以通过try…catch处理异常或者通过throw…throws声明抛出异常。
六、自定义异常
语法:
class 自定义异常 extends 异常类型{
//构造方法
}
public class MyException extends RuntimeException {
//定义无参构造方法
public MyException() {
super();
}
//定义有参构造方法
public MyException(String message) {
super(message);
}
}
注意:子类重写父类的方法,其子类抛出的异常类型只能小于或等于被重写的父类所抛出的异常类型。
七、开源日志记录工具log4j
1.作用:把异常信息长久保存到文件。
2.学习步骤:
①导入jar包
选择项目右击New一个"Folder"文件,将jar包复制进来,选中jar包右击选择Build Path–>Add Build Path即可。
②定义配置文件:log4j.properties(固定文件名+固定位置)
位置:必须在src目录下
③使用Logger
3.配置文件
### 设置输出级别和输出目的地,debug级别,目的地可以是多个 ###
log4j.rootLogger=debug, stdout,logfile
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err ###目标属性配置输出到System.err,控制台显示字体颜色为红色,默认System.out为黑色####
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout ###以简单格式布局###
### 把日志信息输出到文件:jbit.log ###
log4j.appender.logfile=org.apache.log4j.FileAppender ###输出到log文件###
log4j.appender.logfile.File=jbit.log ###文件的名称###
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout ###自定义格式###
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l %F %p %m%n ###%d是日志的日期和时间
%I用来输出日志事件的发生位置;%F是输出文件名;%p是输出优先级;%m是信息;%n是回车换行
①输出级别:fatal:指出严重的错误事件将会导致应用程序的退出。
error:指出虽然发生错误事件,但仍然不影响系统的继续运行。
warn:表明出现潜在错误的情形。
info:在粗粒度级别上指明消息,强调应用程序的运行过程。
debug:指出细粒度信息事件,对调试应用程序时非常有帮助的。
fatal > error > warn > info > debug
②目的地Appender
1.控制台
2.log文件
③日志布局类型Layout
SimpleLayout:简单格式,它输出级别Level,然后跟着一个破折号,最后是日志消息。
HTMLLayout:格式化日志输出为HTML表格。
PatternLayout:自定义格式,需要配置layout.ConversionPattern属性来自定义输出格式,若没有配置该属性,则使用默认的转换模式。
④转换模式ConversionPattern
%d:用来设置输出日志的日期和时间
%m:用来输出代码中指定的消息
%n:用来输出一个回车换行符
%I:用来输出日志事件的发生位置,包括类名、发生的线程、以及在代码中的行数。
%p:用来输出优先级
%F:用来输出文件名
%M:用来输出方法名