Java 异常打印

目录

一、测试案例

二、控制台展示

三、日志文件打印

四、区别 

五、源码展示

5.1.e.toString()与getMessage()

5.2.e    

5.3.e.getStackTrace()

六、小言 


一、测试案例

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @ClassName: T2
 * @Author: BlueBlue
 * @Description: 异常测试
 * @Date: 2023/5/9 0009 10:51
 */
public class T2 {

    private static Logger logger = LoggerFactory.getLogger(T2.class);

    public static void main(String[] args) {
        try{
            List list = null;
            list.add("1");
            list.add("2");
            for (Object a: list) {
                System.out.println(a);
            }
        }catch (Exception e){
            logger.info("toString:"+e.toString());
            logger.info("getMessage:"+e.getMessage());
            logger.info("getStackTrace:"+e.getStackTrace());
            logger.info("e:"+e);
            e.printStackTrace();
        }
    }
}

二、控制台展示

2023-05-10 14:56:15.317  INFO   --- [           main] 
com.task.test.T2           : toString:java.lang.NullPointerException

2023-05-10 14:56:15.326  INFO   --- [           main] 
com.task.test.T2           : getMessage:null

2023-05-10 14:56:15.327  INFO   --- [           main] 
com.task.test.T2           : getStackTrace:[Ljava.lang.StackTraceElement;@475530b9

2023-05-10 14:56:15.328  INFO   --- [           main] 
com.task.test.T2           : e:java.lang.NullPointerException

java.lang.NullPointerException
	at com.task.test.T2.main(T2.java:22)

三、日志文件打印

四、区别 

        本文测试了e、e.toString()、e.getMessage()、e.getStackTrace()、e.printStackTrace(); 这五种异常打印,由上述测试案例可以看出:

        1)e、e.toString() 和 e.printStackTrace(); 打印效果相同,都将Exception展示出来了,获取的信息包括异常类型和异常详细消息

        但e.printStackTrace();显示的更详细,具体到了某一行,缺点是不能输出到日志文件中,但可以手动定义代码,写入日志文件。

        关于e,下面会进行详细介绍,此处不再介绍。

        2)e.getMessage()只是获取了异常的详细消息字符串,同时输出到日志文件中。

        3)e.getStackTrace()是返回一个表示该线程 堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一 个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈 顶,它是该数组中最新的方法调用。最后一个元素代表堆栈 底,是该数组 中最旧的方法调用。

五、源码展示

5.1.e.toString()与getMessage()

    /**
     * Returns a short description of this throwable.
     * The result is the concatenation of:
     * <ul>
     * <li> the {@linkplain Class#getName() name} of the class of this object
     * <li> ": " (a colon and a space)
     * <li> the result of invoking this object's {@link #getLocalizedMessage}
     *      method
     * </ul>
     * If {@code getLocalizedMessage} returns {@code null}, then just
     * the class name is returned.
     *
     * @return a string representation of this throwable.
     */

    /**
     * 返回一个简短的描述关于此异常
     * 获取此异常的根路径和方法名称
     * 返回是此类中某方法的返回
     * 三目运算
     */
    public String toString() {
        String s = getClass().getName();
        String message = getLocalizedMessage();
        return (message != null) ? (s + ": " + message) : s;
    }



    /**
     * Creates a localized description of this throwable.
     * Subclasses may override this method in order to produce a
     * locale-specific message.  For subclasses that do not override this
     * method, the default implementation returns the same result as
     * {@code getMessage()}.
     *
     * @return  The localized description of this throwable.
     * @since   JDK1.1
     */
    public String getLocalizedMessage() {
        return getMessage();
    }


    /**
     * Returns the detail message string of this throwable.
     *
     * @return  the detail message string of this {@code Throwable} instance
     *          (which may be {@code null}).
     */
    public String getMessage() {
        return detailMessage;
    }


    /**
     * Specific details about the Throwable.  For example, for
     * {@code FileNotFoundException}, this contains the name of
     * the file that could not be found.
     *
     * @serial
     */
    private String detailMessage;

        toString上面的是英文注释,能看懂的尽量看英文,因为英文写的更详细,中文翻译会出现不准确。 

        e.toString在调用的过程中,调用了getMessage()方法,返回异常的详细信息。

5.2.e    

 这里的 e 就是一个类型为 Exception 的异常对象。当然异常类型和对象名都可以随着自己的需求偏好进行更换,只是大家都习惯了用 e 对异常对象进行命名而已。把它补全可能更方便理解:

Exception e = new Exception("运行时异常");

同时,既然它是对象,也有可能存在自己的方法。不写,默认为无参构造。

代码较多,直接截图展示:

重新抛出异常——fillInStackTrace() 

        fillInStackTrace会首先判断stackTrace是不是为null,如果不为null,则会调用native方法fillInStackTrace将当前线程的栈帧信息记录到此Throwable中 。

        stackTrace 记录当前异常堆栈信息,数组中每一个StackTraceElement表示当前当前方法调用的一个栈帧,表示一次方法调用。

        backtrace 当本地代码保存在slot中的一些栈的回溯指针

       
StackTraceElement中保存的有当前方法的类名、方法名、文件名、行号信息。

5.3.e.getStackTrace()

        提供对printStackTrace()打印的堆栈跟踪信息的编程访问。堆栈跟踪元素数组,每个元素表示一个堆栈帧。数组的第零元素(假设数组的长度为非零)表示堆栈的顶部,这是顺序中的最后一次方法调用。
        在某些情况下,某些虚拟机可能从堆栈跟踪中忽略一个或多个堆栈帧。在极端情况下,不包含堆栈跟踪信息的虚拟机允许从此方法返回零长度数组。一般来说,此方法返回的数组将包含由printStackTrace打印的每个帧的一个元素。写入返回的数组不会影响以后对此方法的调用。
        返回:一个堆栈跟踪元素数组,表示与此throwable相关的堆栈跟踪。 

        getStackTrace()返回的是通过getOurStackTrace方法获取的StackTraceElement[]数组,而这个StackTraceElement是ERROR的每一个cause by的信息。使用者可以根据自己的需求去得到打印信息,相比printStackTrace()会更细一些。

        printStackTrace()返回的是一个void值,但是可以看到其方法内部将当前传入打印流锁住,然后同样通过getOurStackTrace方法获取的StackTraceElement[]数组,只不过printStackTrace()方法直接打印出来了。

六、小言 

        知道不同的日志打印,是开发的基础使用。研究源码是为了弄懂这些方法是怎样实现的,方便进阶版自定义异常。 但自定义异常,本文不做介绍。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值