Java学习(超详细)十(异常与Log4j)

目录

1.异常

1.1 生活中的异常

1.2 程序中的异常

1.3 什么是异常

1.4 什么是异常处理

2.try-catch

2.1 try-catch-正常

2.2 try-catch-异常

2.3 try-catch-不匹配

2.4 常见的异常类型

2.5 try-catch-finally-exit

2.6 try-catch-finally-return

2.7 多重catch块

3.异常

4.Log4j


1.异常

1.1 生活中的异常

场景:每天我们按照规律上下班,上下学,突然有一天你出了交通事故,导致你接下来的行程无法继续,这就是我们生活中的异常

1.2 程序中的异常

示例:

(1)这是一个非常简单的一段代码,毫无疑问可以运行,但是运行时发生意外怎么办呢,比如除数输入0,或者输入的不是数字

        Scanner in = new Scanner(System.in);
        System.out.print("请输入被除数:");
        int num1 = in.nextInt();
        System.out.print("请输入除数:");
        int num2 = in.nextInt();
        System.out.println(String.format("%d / %d = %d", num1, num2, num1/ num2));
        System.out.println("感谢使用本程序!");

(2)我们用if-else去判断规避这些意外 (这里我们只对除数进行了处理),但是我们发现代码变得非常冗长,而且在其它场景我们可能无法把所有的意外都考虑到写出来,另一方面太长了,太耗费精力了

        Scanner in = new Scanner(System.in);
        System.out.print("请输入被除数:");
        int num1 = in.nextInt();
        System.out.print("请输入除数:");
        int num2 = 0;
        if (in.hasNextInt()) { // 如果输入的除数是整数
            num2 = in.nextInt();
            if (0 == num2) { // 如果输入的除数是0
                System.err.println("输入的除数是0,程序退出。");
                System.exit(1);
            }
        } else { // 如果输入的除数不是整数
            System.err.println("输入的除数不是整数,程序退出。");
            System.exit(1);
        }
        System.out.println(String.format("%d / %d = %d", num1, num2, num1/ num2));
        System.out.println("感谢使用本程序!");

(3)前面抛砖引玉,这里引出本章节学习的异常 ,这里有小伙伴可能疑问,不是说上面的代码太长了吗,这里明显更长。但是这里只是一个简单的案例,如果到一个更复杂的场景,我们用上面的方法去诊断异常是会累死人的。下面我们将进入异常的学习

        Scanner in = new Scanner(System.in);
        System.out.print("请输入被除数:");
        int num1 = in.nextInt();
        System.out.print("请输入除数:");
        try {
            int num2 = in.nextInt();
            System.out.println(String.format("%d / %d = %d", num1, num2, num1/ num2));
        }catch (InputMismatchException e1) {
            System.err.println("输入的不是整数");
            e1.printStackTrace();
            return;
        } catch (ArithmeticException e2) {
            System.err.println("除数不能为0");
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("00000)))))))");
        }
        System.out.println("感谢使用本程序!");

1.3 什么是异常

场景:正常情况下代码不会出现的场景

1.4 什么是异常处理

场景:如果代码出现与正常场景相悖的场景,需要代码去进行异常处理(当然也有代码处理不了的异常,那就叫error了)

2.try-catch

2.1 try-catch-正常

场景:如果try中的代码正常运行,则try-catch结构如同虚设,不起作用

2.2 try-catch-异常

核心要点:

如果try中的代码中同时出现多个可能出现异常的场景,只会捕获一次异常,也就是说只会执行一次catch模块分支【捕获的顺序是由上至下】

try{

//代码(存放你希望被执行的代码,这里的代码可能有异常,也可能没有异常)

}catch(异常类型  异常名称变量){

//异常处理的具体细节【捕获异常】

}

一般捕获遵循的规则是

规则1是 上小下大

规则2是 如果只捕获小的 不捕获大的(Exception)会导致异常种类捕获不完整

规则3是 如果只捕获大的 不捕获小的(具体的Exception)会导致捕获异常无法具体定位

规则4是 如果捕获的顺序不合理,比如上大下小,【由于代码的执行顺序是由上到下】,会导致只捕获大的异常,之后具体小的异常不再捕获【原因是异常只捕获一次】

2.3 try-catch-不匹配

 核心要点:如果没有捕获得到对应的异常,则try catch失效

例如:上面的案例中你只捕获算数异常,当你输入不是整数发生异常时,try-catch则捕获不到,这也是为什么有上面的规则一说。

 

2.4 常见的异常类型

2.5 try-catch-finally-exit

 核心要点:finally会在程序正常或是异常的情况都执行,做补充,但是有一个特例,就是在catch中加入System.exit(0/1)的行为,中断虚拟机,退出程序,则不执行finally语句。

2.6 try-catch-finally-return

核心要点:先执行finally,后执行return

2.7 多重catch块

引发多种类型的异常

        排列catch 语句的顺序:先子类后父类(先小后大)

        发生异常时按顺序逐个匹配

        只执行第一个与异常类型匹配的catch语句

3.异常

3.1 声明异常【系统声明】

public class Demo01 {
    //1.创建 已经声明异常的show()方法【提示这个方法中可能会有异常,也可能没有异常】
    public static void show()throws Exception{
    }

//    public static void main(String[] args) {
    //调用已经声明异常的方法【第一种调用方式】
//        try{
//            show();
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//    }
    
    //调用已经声明异常的方法【第二种调用方式】
    public static void main(String[] args)throws Exception {
        show();
    }
}

3.2 抛出异常【人为抛出】

注意:throw的使用必须在已经系统声明异常的方法中使用

public class Demo02 {
    private String sex = "男";
    public void show()throws Exception{
        if (sex.equals("男")||sex.equals("女")){
            System.out.println("yes");
        }else {
            //人为抛出一个异常
            throw new Exception("no!!!");
        }
    }
}

3.3 异常的分类

1.异常分两大类:Error、Exception

  1. 错误Error          定义:无法用代码去解决
  2. 异常 Exception     定义:可以用代码去捕获(解决)

2.Exception分两类:检查时异常,运行时异常

  1. 检查时异常(Checked Exception)  定义:代码运行前(编译时)必须处理
  2. 运行时异常(Runtime Exception)   定义:代码编译时不强制处理
public class Demo03 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        //运行时异常(Runtime Exception),不加try-catch或throws也可以运行
        try {
            int a = scanner.nextInt();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //检查时异常(Checked Exception),如果不加try-catch或throws会报错,不可运行
        File file = new File("");
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.Log4j

Log4j

1. 定义:开源日志记录工具

2. 功能实现以“文件”形式记录异常信息、程序正常运行关键步骤信息

3. Log4j应用

日志级别顺序:debug -> info -> warn ->error

在配置文件中定义的级别,比如定义了info则比info级别低的日志信息都不再输出

具体掌握用法

        (1)在项目中加入log4j的jar包

        (2)引入log4j.properties文件

        (3)修改配置

        (4)调试

log4j.properties文件内容示例:

第一行表示该日志记录的级别,以及解释当前文件是什么

第二段是将日志信息输出到控制台

第三段是将日志信息存储到my.log文件中

log4j.rootLogger=debug, stdout,logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.err

log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

log4j.appender.logfile=org.apache.log4j.FileAppender

log4j.appender.logfile.File=my.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

使用示例: 

 private static Logger logger= Logger.getLogger(Demo01.class.getName());
    public static void main(String[] args) {
        try {
            Scanner in = new Scanner(System.in);
            System.out.print("请输入被除数:");
            int num1 = in.nextInt();
            System.out.print("请输入除数:");
            int num2 = in.nextInt();
            System.out.println(String.format("%d / %d = %d", num1, num2, num1
                    / num2));
            logger.debug(String.format("%d / %d = %d", num1, num2, num1
                    / num2));
        } catch (InputMismatchException e) {
            logger.debug("被除数和除数必须是整数。");
        } catch (ArithmeticException e) {
            logger.debug("**********除数不能为零。");
        } catch (Exception e) {
            logger.debug("其他异常",e);
        } finally {
            System.out.println("感谢使用本程序!");
        }
    }

猜你喜欢

转载自blog.csdn.net/jojo_oulaoula/article/details/131231632