2019.3.18 异常处理和日志相关
异常(Exception)
-
编译期间出现的问题有什么?
- 1.异常(Exception)
- 2.警告(Warning)
- 3.错误(Error)
-
常见的异常有哪些?
- 1.数组越界
- 2.空指针异常
- 3.控制台输入异常
- 4.栈溢出异常(内存溢出)
那么,如果出现了异常,用什么方法来解决?
此时引入 try/catch/finally(捕获/处理/结束)
我们假设引入一个最简单的异常:算术异常
public class ForthClass {
public static void main(String[] args) {
int a = 1/0;
System.out.println(a);
System.out.println("测试");
}
}
因为分母不能为0,所以此时,控制台会输出异常,如下图所示:
如图所见,当系统运行到a为异常时就不会继续往下运行了,所以后一个输出的“测试”语句不会被执行。
所以我们需要try/catch/finally(捕获/处理/结束)方法,请看下面一段代码:
try{
try{
int a = 1/0;
}catch (ArithmeticException e){ //括号中填写的是异常名 也可以只写Exception
e.printStackTrace(); //打印异常,不过输出的是红字,然后继续运行
}finally {
System.out.println("测试finally"); //无论上面发生了啥,走没走catch 最后都会执行finally块
}
这里给出了异常的解决方法——
将可能会发生异常的语句放入try的大括号中,catch后的小括号中填写一个新建的异常名,finally为最后的结束块。
注意,不管程序运行走没有catch,走了几个catch,最后都要执行finally块中的语句。
异常也可以进行嵌套,请看下面一段代码:
try{
try{int a = 1/0;
}catch (ArithmeticException e){
System.out.println("可以嵌套");
e.printStackTrace();
}
int[] b = new int[10];
b[20] = 100;
}catch (ArithmeticException e){
e.printStackTrace();
}catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
System.out.println("数组越界");
}finally {
System.out.println("测试finally");
}
System.out.println("hello");
}
抛出异常
先编写一个有异常语句的方法:
public static void test() throws Exception {
//模拟抛出异常
try{
int[]b = new int[10];
b[30] = 200;
}catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
throw new Exception("数组越界"); //throw就是抛出异常的语句
}finally {
System.out.println("测试");
}
}
注意,不管是否抛出异常,finally都要执行
接下来编写主函数:
public static void main(String[] args) throws ArrayIndexOutOfBoundsException{
//在上述语句中,throws后为抛出异常,谁调用这个方法异常就由谁来处理
try {
test();
} catch (Exception e) {
e.printStackTrace();
}
}
总结
- 异常的运行机制
- 1.在try块中,如果捕获了异常,那么try块中剩余的代码都不会执行,会直接跳到catch块中;
- 2.在try后 必须要跟catch或finally;
- 3.catch可以有多个 ,用来应对多种异常;
- 4.可以嵌套try-catch-finally;
- 5.抛出异常throw 异常对象,可以再程序任何需要的位置抛出 作用是中断程序的执行 直接抛出异常;
日志
-
为什么要引入日志?
在实际开发中,不可能会有人无时无刻关注服务器的输出内容,需要让程序自己把控制台的内容记录下来。
只要在出现问题的时候,开发人员可以查询log记录。 -
在log中需要关注的级别有哪四个?
- debug
- info
- warn
- error
日志的引入步骤(使用log4j和slf4j日志框架)
- 挂载log4j.jar包/slf4j的两个包
- 在src目录下配置log4j.properties文件
- 编写日志工具类(logger属性和LOGGER输出)
日志工具类:
public class SecClass {
//全部大写
final static Logger LOGGER = Logger.getLogger(SecClass.class); //括号里是当前类的类名
public static void main(String[] args) {
LOGGER.info("test");
LOGGER.debug("测试");
LOGGER.error("错误");
LOGGER.warn("警告");
try {
int a = 1/0;
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(e); //输出error
}
}
}
样例输出:
debug.log
error.log
info.log
warn.log
slf4j.jar相关
- 为什么使用slf4j而不是log4j或其他?
- 1.slf4j只是规定了一堆接口,并不牵扯具体的日志实现 可以让项目脱离某个日志框架的依赖;
- 2.好用;
代码编写:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ThirdClass {
final static Logger LOGGER = LoggerFactory.getLogger(com.lanou.ThirdClass.class); //同log4j
public static void main(String[] args) {
LOGGER.debug("测试模式");
LOGGER.info("信息");
LOGGER.warn("警告");
LOGGER.error("错误");
String name = "张三";
int age = 22;
String address = "大连";
String birthday = "1999-3-20";
String id = "123456789";
LOGGER.info("我叫:{},今年:{},家住在:{},生日是:{},身份证号是:{}",name,age,address,birthday,id); //方便输出法
}
}
样例输出:
debug.log
error.log
info.log
warn.log
附录(工程、jar包及工具)
- log4j.jar
链接:https://pan.baidu.com/s/1IlFLjm1wKG_JjHn1w4B8QA
提取码:11ws
- slf4j.jar
1.slf4j-api-1.7.25.jar
链接:https://pan.baidu.com/s/1aesO8I6Xr75CYWO2uViOmg
提取码:ncby
2.slf4j-log4j12-1.7.25.jar
链接:https://pan.baidu.com/s/1OFzPby6ngEa1cacoU5Tm6A
提取码:2zzl
- log4j配置文件(log4j.properties)
链接:https://pan.baidu.com/s/1-3z0ShEmuaY8JAWAOclBsg
提取码:w1hr
- 工程:2019318Lesson_10异常处理和日志
链接:https://pan.baidu.com/s/1GaZfm5fJWYAt6KbmlP48QQ
提取码:6g87