Exception异常

参考

java 捕获异常还是抛出异常

java基础(十)捕获异常还是抛出异常

异常分类

1.RuntimeException 在程序中可以完全避免的的异常,不需要捕捉,我们可以通过变成来避免

  • 数组越界异常,只要我在程序里作个判断,如果要访问的数组元素下标和数组的长度作一下比较就知道会不会越界,
  • 空指针异常,如果在访问对象时判断一下对象的变量是否为空就可以了。
  • 0作除数异常
  • 处理Excel文件时NotOfficeXmlFileException

2.非RuntimeException 则是程序无法避免的,需要捕捉

  • IOException,程序正在读一个文件,而这个文件所在磁盘出现了坏道,这就必然会引发IOException,这是不是靠编程高手编写完美的程序就可以法避免得了的,程序所能做的只有出现异常之后怎么处理的问题

 

非RuntimeException处理原则

1.要不要捕捉?----在方法调用的最外层一定要捕获异常,比如在MVC框架中 controller层必须捕获异常。

  • 一般情况下不允许将系统内部的异常不做任何封装处理直接抛给客户端,这样对系统来说会暴露过多信息(异常栈信息都抛给客户端,可能会把SQL结构都抛出去),这是不安全因素
  • 这对用户来说也是不友好的,用户可能看不懂,可能会直接影响未来的业务。
  • 因此,通常需要在controller层封装一些错误码、用户友好语句(系统维护中等等欺骗用户的语句)

捕获的异常怎么办?----不要捕获异常,但是什么也不做

捕获的异常怎么办?----log异常

1.不要用System.out.println(), 它是输出在控制台,在非开发环境是没有帮助的;而且System.out.println()是高代价的,调用它会降低系统吞吐量。

2.不要用异常的printStackTrace()方法,printStackTrace默认会把调用的堆栈打印到控制台上,生成环境中不能访问控制台。

3.应该使用log把异常log到日志文件中

以FileNotFoundException为例,看一下这三种的效果

package com.example.exceptiondemo;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExceptionTest {

    Logger logger = LoggerFactory.getLogger(ExceptionTest.class);

    @GetMapping("/logger")
    public void exceptionTestLog() {
        try {
            readFile();
        } catch (IOException e) {
            // log异常正确做法: 捕获异常,并把异常log到日志文件
            logger.error("Error Message : ",e);
        }
    }

    @GetMapping("/syso")
    public void exceptionTestSyso() {
        try {
            readFile();
        } catch (IOException e) {
            // log异常错误做法: System.out.println
            System.out.println(e.getClass().getName() + " " + e.getMessage());
        }
    }

    @GetMapping("/stack")
    public void exceptionTestStack() {
        try {
            readFile();
        } catch (IOException e) {
            // log异常错误做法: stack trace
            e.printStackTrace();
        }
    }

    public void readFile() throws IOException {
        // read file, if file not exist
        InputStream is = new FileInputStream("C:\\test\\test.xlsx");
        is.close();

    }

}

1.访问/logger方法,在日志文件可以看到如下报错,可以清楚的看到异常信息和发送异常的地方

2.访问/syso方法,日志文件没有任何改变,在控制台可以看到如下。首先syso的开销太大,而且在非开发环境,它是没有帮助的,不可取

3.访问/track,日志文件没有任何改变,在控制台可以看到如下。在非开发环境,它是没有帮助的,不可取。

 

posted on 2020-12-29 17:40  dreamstar  阅读(194)  评论(0编辑  收藏  举报