异常
异常的概念
在Java中,提供了错误捕捉和处理机制,即异常处理机制。
在程序运行过程中发生错误时,Java 允许其不按照正常路径完成任务,由发现错误的方法抛出封装了错误信息的对象
(异常)到其调用程序,发出已经发生问题的信号,然后立即退出。而且,程序并不在调用该方法的代码处继续执行,而是由异常处理机制开始搜索一个能够处理这种特定错误情况的异常处理器。
异常产生的原因
- 编写程序代码中的错误产生的异常,比如数组越界、空指针异常等,这种异常叫做未检查的异常,一般需要在类中处理这些异常
- Java内部错误发生的异常,Java虚拟机产生异常
- 通过throw(抛出异常)语句手动生成的异常,这种异常叫做检查的异常,一般是用来给方法调用者一些必要的信息
异常分类
顶级父类:Throwable
- 编译时异常
- 运行时异常
- 错误
- 自定义异常
- 自定义异常类要继承于Exception类或其子类,或其它异常类。
- 为自定义异常类声明字段(属性)成员、方法成员或重写父类的字段和方法。
- 自定义异常类至少要定义两个构造方法:
- 一个是无参的;
- 另外一个是带 String参数的,目的是将此字符串传递给父构造方法,同时这个String的 信息作为该异常对象的描述信息。
- 最后,起一个能标识异常情况的有意义的名字。
异常处理的五大关键字
- try:对代码进行监控
- catch:发生异常时则立即进入
- finally:不论是否有异常都要执行的(有一种情况不会执行),释放资源
- throw:表示在方法体内已经发生了异常,立即抛出异常,一个throw只能抛出一个异常
- throws:表示在方法声明之处抛出异常,可以写多个异常的名称,逗号分开
只是表示有可能此方法的某处会发生异常,并不代表一定会发生
异常的处理
输出异常内容
System.out.println("异常发生在" + stackTraceElement.getLineNumber() + "行");
System.out.println("异常发生方法名称是" + stackTraceElement.getMethodName());
System.out.println("异常发生类名称是" + stackTraceElement.getClassName());
System.out.println("异常发生的文件是" + stackTraceElement.getFileName());
System.out.println("异常类的名称是:" + e.getClass().getSimpleName());
System.out.println("异常发生的原因是:" + e.getMessage());
异常的处理原则
- 异常信息要交给谁看,就应该通知谁
- 如果本级别不处理,就抛出
- 如果本级别要处理,则捕获
异常处理规则
- 在静态块中的编译时异常必须使用try,没有throws选项
- 子类方法不允许抛出比父类更大的异常,如果父类方法没有抛出异常子类不允许抛出
- finally不一定会被执行;程序未到finally,System.exit(0)
异常的工作原理
- 当程序中发生了异常,JVM会立即创建一个此类异常的实例对象,并将此对象注入给catch
- 在这个对象之中,封装着此次异常发生的所有信息
- 此对象由JVM创建,也会自动销毁
处理拓展
// 除数不能为0,输入不匹配异常
static Logger logger = Logger.getLogger(ExceptionDemo2.class.getName());
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("请输入第一个数:");
int num1 = scanner.nextInt();
logger.info("用户输入了第一个数!");
System.out.println("请输入第二个数:");
int num2 = scanner.nextInt();
System.out.println("两数相除的结果是:");
logger.info("用户输入了第二个数!");
int num3 = num1 / num2;
System.out.println(num3);
} catch (InputMismatchException e) {
logger.error("发生异常了,输入数字不格式不匹配");
logger.error("异常发后的类名:" + e.getClass().getSimpleName());
System.out.println("请输入正确的数值型数据:");
} catch (ArithmeticException e) {
System.out.println("除数不能来零");
} catch (Exception e) {
logger.fatal("出大问题了");
} finally {
System.out.println("最后释放资源");
}
}
异常的工作原理
- 当程序中发生了异常,JVM会立即创建一个此类的实例对象,并将此对象注入给catch
- 在这个对象之中,封装着此次异常发生的所有信息
- 对象由JVM创建,也会自动销毁
打印日志lo4j ,html
Log4j.rootLogger=DEBUG,file1,file2,file3,DB
Log4j.appender.file1=org.apache.log4j.ConsoleAppender
Log4j.appender.file1.Target=System.out
Log4j.appender.file1.layout=org.apache.log4j.SimpleLayout
log4j.appender.file2=org.apache.log4j.FileAppender
Log4j.appender.file2.File=JavaTest.log
Log4j.appender.file2.layout=org.apache.log4j.PatternLayout
Log4j.appender.file2.layout.ConversionPattern=%t;%p;%c;%m%n%d;%L;%n
Log4j.appender.file3=org.apache.log4j.FileAppender
Log4j.appender.file3.File=JavaTest.HTML
Log4j.appender.file3.layout=org.apache.log4j.HTM
存放数据库
Log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://localhost:3306/javatest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
Log4j.appender.DB.driver=com.mysql.cj.jdbc.Driver
Log4j.appender.DB.user=root
Log4j.appender.DB.password=123456
log4j.appender.DB.sqL=INSERTINTOLOGSVALUES('%x','%d{yyyy-MM-ddHH:mm:ss}','%C','%p','%m')
Log4j.appender.DB.layout=org.apache.log4j.PatternLayout