Dấu vết ngăn xếp - 1

"Xin chào! Hôm nay tôi sẽ cho bạn biết dấu vết ngăn xếp là gì. Nhưng trước tiên tôi cần cho bạn biết ngăn xếp là gì."

"Hãy tưởng tượng một đống giấy tờ – chỉ thị cho một nhân viên nhất định. Bạn có thể đặt một nhiệm vụ mới lên trên chồng giấy hoặc bạn có thể nhận một nhiệm vụ từ trên cùng. Điều này có nghĩa là các nhiệm vụ sẽ không được thực hiện theo thứ tự chúng được nhận . Tác vụ được đặt trên ngăn xếp gần đây nhất sẽ là tác vụ đầu tiên được thực hiện. Việc cấu trúc các phần tử của tập hợp theo cách này sẽ tạo thành một ngăn xếp . "

" Java có một bộ sưu tập đặc biệt cho điều đó – Stack . Đó là một bộ sưu tập có các phương thức để 'thêm một phần tử' và 'lấy (lấy) một phần tử'. Như bạn có thể đoán, phần tử được thêm vào sau cùng sẽ là phần tử đầu tiên được thêm vào. được lấy."

"Nghe khá đơn giản."

"Tuyệt. Bây giờ tôi sẽ giải thích dấu vết ngăn xếp là gì."

"Hãy tưởng tượng rằng trong một chương trình Java , phương thức A được gọi là phương thức B , phương thức này được gọi là phương thức C , phương thức này được gọi là phương thức D. Để thoát khỏi phương thức B , trước tiên chúng ta phải thoát khỏi phương thức C và để làm điều đó – trước tiên chúng ta phải thoát khỏi phương thức D. Điều này hành vi giống như một ngăn xếp."

"Tại sao anh nói nó giống nó?"

"Ví dụ, để thực hiện một số nhiệm vụ ở giữa chồng giấy của chúng tôi, trước tiên bạn cần thực hiện tất cả các nhiệm vụ nằm trên đó."

"Có một số điểm tương đồng, nhưng tôi không chắc mình hiểu mọi thứ một cách chính xác."

"Hãy nhìn xem. Một ngăn xếp là một tập hợp các phần tử. Giống như các mảnh giấy trong một đống. Để lấy mảnh giấy thứ ba từ trên xuống, trước tiên bạn cần lấy mảnh thứ hai, và để làm được điều đó, bạn cần lấy mảnh đầu tiên. Bạn luôn có thể đặt và lấy các mảnh giấy, nhưng bạn luôn phải lấy tờ giấy trên cùng trước."

"Điều này cũng đúng đối với các lệnh gọi hàm. Phương thức A gọi phương thức B , phương thức này gọi phương thức C. Để thoát A , trước tiên bạn phải thoát B và để thực hiện điều đó, bạn cần thoát C. "

"Đợi đã. Nếu tôi hiểu những gì bạn đang nói, thì toàn bộ khái niệm về một ngăn xếp tóm tắt lại là 'lấy mảnh giấy được thêm vào cuối cùng' và 'bạn chỉ có thể thoát khỏi phương thức bạn đã nhập gần đây nhất'. Điều đó có chính xác không? "

"Vâng. Chuỗi các cuộc gọi hàm được gọi là 'ngăn xếp cuộc gọi' hoặc đơn giản là 'ngăn xếp'. Hàm cuối cùng được gọi là hàm đầu tiên kết thúc. Hãy xem xét một ví dụ."

Nhận và hiển thị ngăn xếp cuộc gọi hiện tại:
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());
    }
  }
}
Kết quả:
getStackTrace
method3
method2
method1
main

"OK. Tôi hiểu mọi thứ về lệnh gọi hàm. Nhưng StackTraceElement này là gì?"

"Máy Java theo dõi tất cả các lời gọi hàm. Vì thế, nó có một bộ sưu tập đặc biệt - ngăn xếp. Khi một hàm gọi một hàm khác, Máy Java sẽ đặt một đối tượng StackTraceElement mới vào ngăn xếp. Khi một hàm kết thúc, phần tử đó sẽ bị xóa khỏi ngăn xếp. Điều này có nghĩa là ngăn xếp luôn lưu trữ thông tin cập nhật về trạng thái hiện tại của 'ngăn lệnh gọi hàm'. "

"Mỗi đối tượng StackTraceElement chứa thông tin về phương thức được gọi. Cụ thể, bạn có thể lấy tên phương thức bằng cách sử dụng phương thức getMethodName ."

"Bạn có thể thấy cách thức hoạt động của nó trong ví dụ trên:

1) Chúng tôi nhận được ngăn xếp cuộc gọi.

2) Chúng tôi sử dụng vòng lặp for-each để đi qua nó. Tôi hy vọng bạn đã không quên đó là gì.

3) Chúng tôi xuất tên phương thức thành System.out ."

"Thật hấp dẫn! Và cũng không quá phức tạp. Cảm ơn, Rishi!"