Java打印异常堆栈信息,定位异常调用位置

Java语言的异常类Exception包含着异常的全部信息。

现设异常的实例名为ex,所有的异常都是一个除以0的表达式(int i = 1 / 0)所触发的:

1、通过ex.getMessage()可以获取异常信息,如

/ by zero

2、通过ex.toString()可以获取异常类型和异常信息,如

java.lang.ArithmeticException: / by zero

3、通过ex.printStackTrace()可以直接在控制台打印异常的全部信息(包括堆栈),但该函数最好不要直接调用无参数的版本,因为这样会让控制台显示出现错乱。调用printStackTrace时,通过如下方法调用:

StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
ex.printStackTrace(printWriter);
System.out.println(stringWriter.toString());

使用此方法,控制台输出的内容为:

java.lang.ArithmeticException: / by zero
        at ExceptionTest.exec3(ExceptionTest.java:31)
        
at ExceptionTest.exec2(ExceptionTest.java:23)
        
at ExceptionTest.exec1(ExceptionTest.java:15)
        
at ExceptionTest.main(ExceptionTest.java:39)

如果使用的是Eclipse的控制台,异常类名和指明行数的错误堆栈都会生成相应的跳转链接。

4、通过ex.getStackTrace()可以获取堆栈信息,这是 ex.printStackTrace() 外的另一种获取异常堆栈信息的方法。通过此方法可以定制化输出堆栈信息。

System.out.println(ex.getClass().getName() + ": " + ex.getMessage());
StringBuilder sbException = new StringBuilder();

for (StackTraceElement ele : ex.getStackTrace()) {
    sbException.append(MessageFormat.format(
"\tat {0}.{1}({2}:{3})\n",
        ele.getClassName(), ele.getMethodName(), ele.getFileName(), ele.getLineNumber()));;
}
System.out.println(sbException);

打印出的异常堆栈为:

java.lang.ArithmeticException: / by zero
        at ExceptionTest.exec3(ExceptionTest.java:31)
        
at ExceptionTest.exec2(ExceptionTest.java:23)
        
at ExceptionTest.exec1(ExceptionTest.java:15)
        
at ExceptionTest.main(ExceptionTest.java:39)

最后列一下完整的Java代码:

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;

/**
 *
异常打印测试
 * @文件名称 ExceptionTest.java
 * @
文件作者 Tsybius2014
 * @
创建时间 2016513日 下午6:14:08
 */

public class ExceptionTest {
   
/** 第一层函数 */
    public static void exec1() {
       
try {
            exec2();
        }
catch (Exception ex) {
           
throw ex;
        }
    }
   
/** 第二层函数 */
    public static void exec2() {
       
try {
            exec3();
        }
catch (Exception ex) {
           
throw ex;
        }
    }
   
/** 第三层函数 */
    public static void exec3() {
       
try {
           
int i = 1 / 0;
        }
catch (Exception ex) {
           
throw ex;
        }
    }
   
/** 主函数 */
    public static void main(String[] args) {
       
try {
            exec1();
        }
catch (Exception ex) {
            System.
out.println("--- getMessage ---");
            System.
out.println(ex.getMessage());
            System.
out.println();
            System.
out.println("--- toString ---");
            System.
out.println(ex.toString());
            System.
out.println();
            System.
out.println("--- printStackTrace ---");
            StringWriter stringWriter =
new StringWriter();
            PrintWriter printWriter =
new PrintWriter(stringWriter);
            ex.printStackTrace(printWriter);
            System.
out.println(stringWriter.toString());
            System.
out.println();
            System.
out.println("--- printStackTrace DIY ---");
            System.
out.println(ex.getClass().getName() + ": " + ex.getMessage());
            StringBuilder sbException =
new StringBuilder();
           
for (StackTraceElement ele : ex.getStackTrace()) {
                sbException.append(MessageFormat.format(
"\tat {0}.{1}({2}:{3})\n",
                    ele.getClassName(), ele.getMethodName(), ele.getFileName(), ele.getLineNumber()));;
            }
            System.
out.println(sbException);
        }
    }
}

Java 中,当程序运行时发生异常,JVM 会自动打印异常堆栈信息异常堆栈信息包括异常类型、异常发生的位置调用信息等,可以帮助我们快速定位问题并进行调试。 下面是一个简单的 Java 程序,其中会抛出一个 NullPointerException 异常: ```java public class ExceptionDemo { public static void main(String[] args) { String str = null; System.out.println(str.length()); } } ``` 当我们运行这个程序时,会得到如下的异常堆栈信息: ``` Exception in thread "main" java.lang.NullPointerException at ExceptionDemo.main(ExceptionDemo.java:4) ``` 可以看到,这里抛出了一个 NullPointerException 异常,并且异常发生在程序的第 4 行。通过这个异常堆栈信息,我们就可以快速定位问题所在。 关于即时编译优化和异常堆栈丢失的问题,它们之间的关系可以简单描述为:即时编译优化可能会导致异常堆栈信息丢失。这是因为,为了提高程序的执行效率,JVM 可能会对代码进行一些优化,包括方法内联、循环展开、消除冗余操作等。这些优化可能会使得程序的执行过程变得复杂,从而导致异常堆栈信息丢失。 为了解决这个问题,我们可以通过关闭即时编译优化来保留完整的异常堆栈信息。在 Java 中,可以通过设置系统属性 `-XX:-OmitStackTraceInFastThrow` 来关闭即时编译优化。这样,即使程序发生异常,也能够保留完整的异常堆栈信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值