>Java >java지도 시간 >Java 예외 스택 추적 예제 코드에 대한 자세한 설명

Java 예외 스택 추적 예제 코드에 대한 자세한 설명

黄舟
黄舟원래의
2017-03-17 10:51:331733검색

이 글에서는 주로 Java 예외 스택 추적(Stack Trace)에 대한 자세한 설명과 예제 코드 관련 정보를 소개합니다. 필요한 친구는

Java 예외 스택 추적(Stack Trace) 세부 정보를 참조하세요. 설명

예외가 발생하면 일부 처리가 필요한 경우가 많습니다. 더 간단하고 직접적인 방법은 예외 스택 추적 Stack Trace를 인쇄하는 것입니다. 스택 추적에 관해 말하면 많은 사람들이 나와 같을 것입니다. 첫 번째 반응은 printStackTrace() 메서드입니다. 실제로 이 방법 외에도 스택 트레이스와 관련된 내용이 몇 가지 더 있습니다.

1.printStackTrace()

우선 이 메서드가 Exception 클래스에서 나온 것이 아니라는 점을 분명히 해야 합니다. 여러 생성자를 정의하는 Exception 클래스 자체를 제외하고 모든 메서드는 해당 부모 클래스에서 상속됩니다. 예외와 관련된 메소드는 모두 java.lang.Throwable 클래스에서 상속됩니다. printStackTrace()도 그 중 하나입니다.

이 메소드는 Throwable 객체의 스택 추적 정보를 표준 오류 출력 스트림에 인쇄합니다. 출력의 일반적인 모습은 다음과 같습니다.

java.lang.NullPointerException
     at MyClass.mash(MyClass.java:9)
     at MyClass.crunch(MyClass.java:6)
     at MyClass.main(MyClass.java:3)

출력의 첫 번째 줄은 toString() 메서드의 출력이고, 그 다음 줄의 내용은 이전에 fillInStackTrace() 메서드를 통해 저장한 내용입니다. . 이 방법에 대해서는 나중에 이야기하겠습니다.

예를 살펴보겠습니다.

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    f();
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

이 예의 출력은 다음과 같습니다.

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)

이 예에서는 f() 메서드에서 예외가 발생합니다. , g() 메서드에서 f() 메서드를 호출하고, 기본 메서드에서 예외를 포착하고, 스택 추적 정보를 인쇄합니다. 따라서 출력에는 f->g->main의 과정이 순차적으로 표시됩니다.

2.getStackTrace() 메소드

이 메소드는 printStackTrace() 메소드에 의해 인쇄된 정보에 대한 프로그래밍 방식의 액세스를 제공합니다. 스택 추적 요소의 배열을 반환합니다. 위 출력을 예로 들면, 출력 라인 2-4의 각 라인 내용은 스택 추적 요소에 해당합니다. 이러한 스택 추적 요소를 배열에 저장합니다. 각 요소는 스택의 스택 프레임에 해당합니다. 배열의 첫 번째 요소는 스택의 최상위 요소(위의 f)를 저장합니다. 마지막 요소에 의해 저장된 스택의 맨 아래 요소입니다.

다음은 getStackTrace()를 사용하여 이러한 추적 스택 요소에 액세스하고 출력을 인쇄하는 예입니다.

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    f();
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
      System.out.println("------------------------------");
      for(StackTraceElement elem : e.getStackTrace()) {
        System.out.println(elem);
      }
    }
  }
}

이러한 출력은 기본적으로 다음과 같이 printStackTrace()의 출력과 동일합니다. :

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)
TestPrintStackTrace.f(TestPrintStackTrace.java:3)
TestPrintStackTrace.g(TestPrintStackTrace.java:6)
TestPrintStackTrace.main(TestPrintStackTrace.java:10)

3.fillInStackTrace()

이 방법은 이전에도 언급했습니다. 이 방법을 명확하게 하기 위해 먼저 예외를 포착한 후 다시 발생시키는 문제에 대해 이야기해야 합니다. catch 코드 블록에서 예외를 포착하고 스택 추적을 인쇄한 후 다시 버립니다. 이전 수준 메서드 호출에서 이 예외를 포착하고 스택 추적 정보를 인쇄합니다. 두 스택 추적 정보가 동일합니까? 코드를 살펴보겠습니다.

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    try {
      f();
    }catch(Exception e) {
      e.printStackTrace();
      throw e;
    }
     
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

기본 메서드에서 발생한 예외는 g() 메서드에서 발생합니다. 두 스택 추적에 의해 인쇄되는 정보는 달라야 합니다. 두 번째로 인쇄되었습니다. f에 대한 정보가 없어야 합니다. 하지만 실제로 두 번 출력된 스택 추적 정보는 동일합니다. 출력 결과는 다음과 같습니다.

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:16)
java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:16)

즉, 예외를 잡아서 즉시 던지고, 상위 메소드 호출에서 다시 예외를 잡는 경우 출력되는 스택 추적 정보는 동일합니다. 그 이유는 현재 스레드의 현재 상태에서 궤적 스택의 상태가 Throwabe에 저장되지 않기 때문입니다. 이제 fillInStackTrace() 메서드를 소개합니다. 이 방법은 바로 이런 종류의 보존 작업을 수행하는 것입니다. 이 메서드의 프로토타입을 살펴보겠습니다.

public Throwable fillInStackTrace()

이 메서드에는 반환 값이 있습니다. 반환되는 것은 현재 스택 추적 정보를 저장하는 Throwable 개체입니다. fillInStackTrace() 메서드를 사용한 후 출력되는 스택 추적 정보의 차이점을 살펴보겠습니다. 코드는 다음과 같습니다.

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    try {
      f();
    }catch(Exception e) {
      e.printStackTrace();
      //不要忘了强制类型转换
      throw (Exception)e.fillInStackTrace();
    }
     
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

출력은 다음과 같습니다.

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:17)
java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.g(TestPrintStackTrace.java:11)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:17)

스택은 기본 메소드로 인쇄됩니다. 궤도에는 더 이상 f 관련 정보가 없습니다.

위 내용은 Java 예외 스택 추적 예제 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.