1、异常是什么
异常:
1、就是不正常的意思:
2、指程序在执行过程中,出现的非正常的情况,最终导致jvm非正常停止
3、在java等面向对象的编程语言中,异常本身就是一个类,产生异常就是创建一个异常对象并抛出了一个异常对象,java处理异常的方式就是中断处理
4、异常指的并不是语法错误。语法错误,编译通过不了的,不会产生字节码文件根本不能运行
异常的体系:
异常机制其实是帮助我们找到程序中的问题,异常的根类是java.lang.Throwable,其下有两个子类:java.lang.Error与java.lang.Exception,平常所说的异常指java.lang.Exception
异常体系:
Throwable体系:
Error: //错误
严重错误,无法通过处理的错误,只能事先避免,好比绝症
Exception: //异常
异常产生后可以通过代码的方式纠正,使程序继续运行,且必须处理,好比感冒
RuntimeException //运行时异常
runtime异常:在运行时期检查异常,在编译时期不会被编译器检测(不报错)如数学异常
非RuntimeException //非运行时异常
checked异常:在编译时期就会被检测到,如果不处理异常,则编译失败
2、异常怎么处理
JVM默认处理异常的方式:
如果程序出现了问题,我们没有做任何处理,最终JVM会做默认处理
1、把异常的名称,错误原因及异常出现的位置等信息输出在控制台
2、程序停止执行
try-catch方式处理异常:
定义格式:
try {
/可能出现异常的代码;
} catch(异常类名 变量名) {
//异常的处理代码;
}
执行流程:
1、程序从try里面的代码开始执行
2、出现异常,就会跳转到对应的catch里面执行
3、执行完毕之后,程序还可以继续往下执行
throws方式处理异常:
throws处理异常,又被称之为声明异常,将问题标识出来,,报告给调用者
用于表示当前方法不处理异常,而是提醒该方法的调用者处理异常(抛出异常)
声明异常的格式:
修饰符 返回值类型 方法名() throws 异常类名 {
//这是一个正常的可能出现异常的方法
}
常见方法:
getMessage():获取异常的原因
toString():获取异常的类型和原因
pintStackTrace:获取异常的类型,原因和位置
finally代码块:
有一些特定的代码无论异常是否发生,都需要执行,异常会引发程序跳转,导致后续的代码执行不到,,而finally存放的代码都是一定会被执行的
格式如下:
try {
可能出现异常的代码;
} catch(异常类名 变量名) {
异常的处理代码;
} finally{
释放资源
}
1、finally不能单独使用。必须配合着try...catch使用
2、当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行。
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
3、自定义异常
一个类继承了Exception或者RuntimeException,那么这个类就是异常类
public class 异常类 extends Exception | RuntimeException {
public 异常类() {
}
public 异常类(String message) {
super(message);
}
}
自定义异常代码实现:
// 业务逻辑异常
public class RegisterException extends Exception {
/**
* 空参构造
*/
public RegisterException() {
}
/**
*
* @param message 表示异常提示
*/
public RegisterException(String message) {
super(message);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class Demo {
// 模拟数据库中已存在账号
private static String[] names = {"bilibili","bilibili","bilibili"};
public static void main(String[] args) {
//调用方法
try{
// 可能出现异常的代码
checkUsername("bilibili");
System.out.println("注册成功");//如果没有异常就是注册成功
}catch(RegisterException e){
//处理异常
e.printStackTrace();
}
}
//判断当前注册账号是否存在
//因为是编译期异常,又想调用者去处理 所以声明该异常
public static boolean checkUsername(String uname) throws RegisterException{
for (String name : names) {
if(name.equals(uname)){//如果名字在这里面 就抛出登陆异常
throw new RegisterException("亲"+name+"已经被注册了!");
}
}
return true;
}
}
4、Log4J
日志用来记录用户操作,系统运行状态等,是一个系统的重要组成部分,对于一些简单的小程序,可能不需要在如何记录日志的问题发费太多的精力,作为一个大的程序,要保证长久的运行,就必须考虑日志记录了,依靠良好的日志来保证程序可靠的运行
好的日志:
1、了解线上系统的运行状态
2、快速准确定位线上问题
3、发现系统瓶颈
4、预警系统潜在风险
5、挖掘产品最大价值
不好的日志:
1、对系统的运行状态一知半解,甚至一无所知
2、系统出现的问题无法定位,或者发挥巨大的时间和精力
3、无法发现系统瓶颈,不知优化从何做起
4、无法基于日志对系统运行过程中的错误和潜在风险进行监控和报警
5、对挖掘用户行为和提升产品价值毫无帮助
日志分类:
诊断日志:
1、请求入口和出口
2、外部服务调用和返回
3、资源消耗操作:如读取文件等
3、容错行为:如云硬盘的副本修复操作
4、程序异常:如数据库无法连接
5、后台操作:定期执行删除的线程
6、启动,关闭,配置加载
统计日志:
1、用户访问统计:用户IP,上传下载的数据量和请求耗时等
2、计费日志(如记录用户使用的网络资源或磁盘占用,格式较为严格,便于统计)
审计日志:
对于简单的系统,可以将所有的日志输出到同一个日志文件中,通过不用的关键字进行区分,而对于复杂的系统,将不同需求的日志文件输出到不同的日志文件中是必要的
日志级别:
log4J定义了8个级别的log(除去off和all,可以说分为6个级别)
优先级从高到底依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL
ALL:
TRACE:
DEBUG:
INFO:
WARN:
ERROR:
主要针对一些不可预知的信息,诸如:错误,异常等(log4J默认级别)
FATAL:
指出每个严重的错误事件将会导致应用程序的退出,这种级别的错误,可以直接停止程序了
OFF:
Log4J使用
1、导包
2、导配置文件:log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=log4j.appender.D.File =要保存日志的位置 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = G://logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=log4j.appender.E.File =要保存日志的位置 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =G://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
3、记录日志代码
public class Log4JDemo {
public static void main(String[] args) {
// 获取日志记录器对象
Logger logger = null;
try {
logger = Logger.getLogger(Log4JDemo.class);
int i = 4 / 0;
} catch (Exception e) {
//记录日志信息
logger.debug(e.getMessage());
}
}
}