스택 추적 - 1

"안녕하세요! 오늘은 스택 추적이 무엇인지 알려드리겠습니다. 하지만 먼저 스택이 무엇인지 알려드릴 필요가 있습니다."

"서류 더미를 상상해 보십시오. 특정 직원에 대한 지시입니다. 더미 위에 새 작업을 놓을 수도 있고 위에서 작업을 가져올 수도 있습니다. 이것은 작업이 받은 순서대로 실행되지 않는다는 것을 의미합니다. . 더미에 가장 최근에 배치된 작업이 가장 먼저 실행됩니다. 이러한 방식으로 컬렉션의 요소를 구성하면 스택이 형성됩니다 . "

" Java에는 이를 위한 특별한 컬렉션이 있습니다. Stack 입니다. '요소 추가' 및 '요소 가져오기(가져오기)' 메서드가 있는 컬렉션입니다. 짐작하셨겠지만 마지막에 추가된 요소가 가장 먼저 찍히다."

"오히려 간단하게 들립니다."

"좋아요. 이제 스택 추적이 무엇인지 설명하겠습니다 ."

"자바 프로그램 메서드 A 에서 메서드 B 를 호출 하고 메서드 C 를 호출한 다음 메서드 D 를 호출한다고 상상해 보십시오. 메서드 B 를 종료하려면 먼저 메서드 C를 종료해야 합니다 . 그렇게 하려면 먼저 메서드 D를 종료해야 합니다 . 이 동작은 스택과 유사합니다."

"왜 닮았다고 하세요?"

"예를 들어, 종이 더미 중간에 있는 작업을 수행하려면 먼저 그 위에 있는 모든 작업을 실행해야 합니다."

"비슷한 부분이 있긴 하지만 제가 모든 것을 올바르게 이해했는지 확신이 서지 않습니다."

"보세요. 스택은 요소의 집합입니다. 무더기의 종이 조각과 같습니다. 위에서 세 번째 종이를 가져오려면 먼저 두 번째 종이를 가져와야 하고, 그러려면 첫 번째 종이를 가져와야 합니다. 종이는 항상 넣고 빼지만 맨 위의 종이는 항상 먼저 가져가야 합니다."

"함수 호출의 경우에도 마찬가지입니다. 메서드 A 는 메서드 C 를 호출하는 메서드 B 를 호출합니다 . A 를 종료하려면 먼저 B를 종료해야 하며 그렇게 하려면 C 를 종료해야 합니다 ."

"잠깐. 무슨 말인지 이해가 된다면 스택의 전체 개념은 '마지막에 추가된 종이를 가져가라'와 '가장 최근에 입력한 메서드만 종료할 수 있다'로 요약됩니다. 정확합니까? "

"예. 함수 호출의 순서를 '호출 스택' 또는 간단히 '스택'이라고 합니다. 마지막으로 호출된 함수가 가장 먼저 종료되는 함수입니다. 예를 들어 보겠습니다."

현재 호출 스택을 가져오고 표시합니다.
public class ExceptionExample
{
  public static void main(String[] args)
  {
    method1();
  }

  public static void method1()
  {
    method2();
  }

  public static void method2()
  {
    method3();
  }

  public static void method3()
  {
     StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
    for (StackTraceElement element : stackTraceElements)
    {
       System.out.println(element.getMethodName());
    }
  }
}
결과:
getStackTrace
method3
method2
method1
main

"알겠습니다. 함수 호출에 대한 모든 정보를 얻었습니다. 하지만 이 StackTraceElement는 무엇입니까?"

"Java Machine은 모든 함수 호출을 추적합니다. 이를 위해 특별한 컬렉션인 스택이 있습니다. 한 함수가 다른 함수를 호출하면 Java Machine은 새로운 StackTraceElement 개체를 스택에 넣습니다. 함수가 완료되면 해당 요소가 제거 됩니다 . 이것은 스택 이 항상 '함수 호출 스택'의 현재 상태에 대한 최신 정보를 저장한다는 것을 의미합니다. "

"각 StackTraceElement 개체에는 호출된 메서드에 대한 정보가 포함되어 있습니다. 특히 getMethodName 메서드를 사용하여 메서드 이름을 가져올 수 있습니다."

"위의 예에서 이것이 어떻게 작동하는지 확인할 수 있습니다.

1) 호출 스택을 얻습니다.

2) for-each 루프를 사용하여 통과합니다. 그것이 무엇인지 잊지 않으셨으면 좋겠습니다.

3) 메서드 이름을 System.out 에 출력합니다 ."

"매혹적이야! 너무 복잡하지도 않아. 고마워, 리시!"