Java 异常中 e.getMessage() 和 e.toString() e.printStackTrace()的区别

Java 异常中 e.getMessage() 和 e.toString() e.printStackTrace()的区别
一、概述

        在java异常体系中,要打印异常信息,可以通过:e.getMessage() 、 e.toString() e.printStackTrace() 等方法打印出 一些 异常信息。已知的是这些方法都可以打印异常信息,但是这些方法打印的异常信息 都不相同,那么问题来啦: 这些方法打印异常信息的区别是?日常开发工作中,该用哪个方法打印异常信息呢?

二、代码理解

        1、 Junit 单元测试 --- 模拟异常信息输出

@Test
public void test(){
    int num = 0 ;
    try {
        int  i = 3/num ;
    } catch (Exception e) {
        System.out.println(" e.printStackTrace() ==== start");
        e.printStackTrace();
        System.out.println(" e.printStackTrace() ==== end ");
        System.out.println();
 
        System.out.println(" e.getMessage() ==== start");
        System.out.println(e.getMessage());
        System.out.println(" e.getMessage() ==== end");
 
        System.out.println();
        System.out.println(" e.toString() ==== start");
        System.out.println(e.toString());
        System.out.println(" e.toString() ==== end");
 
        System.out.println();
        System.out.println(" e.getExceptionToString() ==== start");
        System.out.println(Exceptions.getExceptionToString(e));
        System.out.println(" e.getExceptionToString() ==== end");
    }
}


        1.1、输出结果如下:

e.printStackTrace() ==== start
java.lang.ArithmeticException: / by zero
    at com.runcode.springboottourist.test.ExpTest2.test(ExpTest2.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
 e.printStackTrace() ==== end 
 
 e.getMessage() ==== start
/ by zero
 e.getMessage() ==== end
 
 e.toString() ==== start
java.lang.ArithmeticException: / by zero
 e.toString() ==== end
 
 e.getExceptionToString() ==== start
java.lang.ArithmeticException: / by zero
    at com.runcode.springboottourist.test.ExpTest2.test(ExpTest2.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
 
 e.getExceptionToString() ==== end


        1.2、结果分析 :

e.printStackTrace(): 打印完整的异常堆栈信息
e.getMessage(): 打印 异常的原因
e.toString(): 打印 异常类型 和 异常的原因
e.getExceptionToString(): 打印完整的异常堆栈信息


        2、web 环境下 --- 模拟异常信息输出

@RequestMapping("/exp")
@ResponseBody
public String exp(String key){
    int num = 0 ;
    try {
        int  i = 3/num ;
    } catch (Exception e) {
        System.out.println(" e.printStackTrace() ==== start");
        e.printStackTrace();
        System.out.println(" e.printStackTrace() ==== end ");
 
        System.out.println();
        System.out.println(" e.getMessage() ==== start");
        System.out.println(e.getMessage());
        System.out.println(" e.getMessage() ==== end");
 
        System.out.println();
        System.out.println(" e.toString() ==== start");
        System.out.println(e.toString());
        System.out.println(" e.toString() ==== end");
 
        System.out.println();
        System.out.println(" e.getExceptionToString() ==== start");
        System.out.println(Exceptions.getExceptionToString(e));
        System.out.println(" e.getExceptionToString() ==== end");
    }
    return "success";
}


        2.1、输出结果如下:

e.printStackTrace() ==== start
 e.printStackTrace() ==== end 
 
 e.getMessage() ==== start
/ by zero
 e.getMessage() ==== end
 
 e.toString() ==== start
java.lang.ArithmeticException: / by zero
 e.toString() ==== end
 
 e.getExceptionToString() ==== start
java.lang.ArithmeticException: / by zero
    at com.runcode.springboottourist.ExpController.exp(ExpController.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
 
 e.getExceptionToString() ==== end
java.lang.ArithmeticException: / by zero
    at com.runcode.springboottourist.ExpController.exp(ExpController.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)


2.2、结果分析:

  • e.printStackTrace(): 打印完整的异常堆栈信息 (在e.getExceptionToString 后面)
  • e.getMessage(): 打印 异常的原因
  • e.toString(): 打印 异常类型 和 异常的原因
  • e.getExceptionToString(): 打印完整的异常堆栈信息

三、总结

        1、Exceptions.getExceptionToString(e) 方法,参考这里:java中将异常Exception转化为String字符串输出_HaHa_Sir的博客-CSDN博客

        2、e.getMessage() 和 e.toString() 方法: 打印的异常信息太少,没有具体的堆栈信息,不利于问题的定位处理, 不建议使用!

        3、e.printStackTrace() 和 Exceptions.getExceptionToString(e) 方法:都可以打印完整的异常堆栈信息; 二者的区别是: e.printStackTrace() 在遇到大量并发访问 且 出现异常时,会发生:内存被占满的情况,导致服务挂掉,不可用 ...

        4、日常开发中,会使用 log.error 来打印异常信息,下面比较几种 log.error 打印异常信息的区别:

@RequestMapping("/log")
@ResponseBody
public String log(String key){
    int num = 0 ;
    try {
        int  i = 3/num ;
    } catch (Exception e) {
 
        System.out.println(" log.error(\"exp failure \"+ e) ==== start");
        log.error("exp failure "+ e);
        System.out.println(" log.error(\"exp failure \"+ e) ==== end");
        System.out.println();
 
        System.out.println(" log.error(\"exp failure {}\"+ e) ==== start");
        log.error("exp failure {}" + e);
        System.out.println(" log.error(\"exp failure {}\"+ e) ==== end");
        System.out.println();
 
        System.out.println(" log.error(\"exp failure {}\", e) ==== start");
        log.error("exp failure {}" , e);
        System.out.println(" log.error(\"exp failure {}\" ,e) ==== end");
        System.out.println();
 
        System.out.println(" log.error(\"exp failure {}\", getExceptionToString) ==== start");
        log.error("exp failure {}" , Exceptions.getExceptionToString(e));
        System.out.println(" log.error(\"exp failure {}\" ,getExceptionToString) ==== end");
    }
    return "success";
}

        4.1、输出结果:

1、 log.error("exp failure "+ e) ==== start

2022-09-20 16:48:51.783 ERROR 34220 --- [nio-8080-exec-8] c.r.springboottourist.ExpController : exp failure java.lang.ArithmeticException: / by zero

log.error("exp failure "+ e) ==== end

2、 log.error("exp failure {}"+ e) ==== start

2022-09-20 16:48:51.783 ERROR 34220 --- [nio-8080-exec-8] c.r.springboottourist.ExpController : exp failure {}java.lang.ArithmeticException: / by zero

log.error("exp failure {}"+ e) ==== end

3、 log.error("exp failure {}", e) ==== start

2022-09-20 16:48:51.784 ERROR 34220 --- [nio-8080-exec-8] c.r.springboottourist.ExpController : exp failure {}

java.lang.ArithmeticException: / by zero

-- 省略异常堆栈信息

log.error("exp failure {}" ,e) ==== end

4、 log.error("exp failure {}", getExceptionToString) ==== start

2022-09-20 16:48:51.785 ERROR 34220 --- [nio-8080-exec-8] c.r.springboottourist.ExpController : exp failure java.lang.ArithmeticException: / by zero

-- 省略异常堆栈信息

log.error("exp failure {}" ,getExceptionToString) ==== end

4.2、结果分析:

  • 1、2 两种情况:都是属于拼接字符串,实际调用的是 e.toString() 方法
  • 3 :使用了占位符输出日志,打印了完整的堆栈信息, 但是 占位符 貌似没被识别到。
  • 4 :使用了占位符输出日志,打印了完整的堆栈信息, 将异常对象转换为字符串后, 占位符 被识别到。

        5、日常开发工作中,该用哪个方法打印异常信息呢:

1.异常对象转换为字符串:

String errMsg = Exceptions.getExceptionToString(e);


2. 日志输出:

log.error("exp failure : {}",errMsg);

你可能感兴趣的:(java,java)