Setelah breakpoint dipasang, kita perlu menelusuri kode baris demi baris untuk memahami alur eksekusi dan perubahan state. IntelliJ menyediakan empat operasi step utama: Step Over, Step Into, Step Out, dan Drop Frame. Setiap operasi memiliki semantik berbeda dan dipakai pada konteks berbeda. Pada chapter ini kita akan membedah masing-masing operasi, kapan menggunakannya, dan jebakan umum yang sering dialami pemula. Kode contoh akan menjelaskan skenario step yang dapat kita latih.
Empat Operasi Step #
| Operasi | Shortcut | Perilaku | Kapan dipakai |
|---|---|---|---|
| Step Over | F8 | Eksekusi baris saat ini; tidak masuk ke method | Method library sudah yakin benar |
| Step Into | F7 | Masuk ke method yang dipanggil di baris saat ini | Method curiga, ingin periksa detail |
| Step Out | SHIFT+F8 | Selesaikan method saat ini, berhenti di pemanggil | Sudah selesai memeriksa method, ingin keluar |
| Drop Frame | tombol di panel Frames | Kembali ke pemanggil, ulang pemanggilan | Ingin mengulang dengan input berbeda |
Kode Demo Step-Through #
Program berikut memanggil beberapa method bertingkat: urutkan, hitungStatistik, dan ulangiPesan. Kita akan memasang breakpoint di baris val hasil = urutkan(data) dan menelusuri eksekusi.
fun main() {
println("=== Demo Step-Through Debugging ===")
val data = listOf(5, 3, 8, 1, 9, 2)
// Step Over: eksekusi baris tanpa masuk ke fungsi `urutkan`
val hasil = urutkan(data)
println("Hasil urut: $hasil")
// Step Into: masuk ke dalam fungsi `hitungStatistik`
val stats = hitungStatistik(data)
println("Statistik: min=${stats.first}, max=${stats.second}")
// Demo Drop Frame: bila ingin mengulang pemanggilan fungsi
ulangiPesan("Halo", 3)
}
fun urutkan(daftar: List<Int>): List<Int> {
// Step Into akan masuk ke sorted()
return daftar.sorted()
}
fun hitungStatistik(daftar: List<Int>): Pair<Int, Int> {
val min = daftar.minOrNull() ?: 0
val max = daftar.maxOrNull() ?: 0
return Pair(min, max)
}
fun ulangiPesan(pesan: String, jumlah: Int) {
for (i in 1..jumlah) {
// Drop Frame dari sini akan kembali ke pemanggil ulangiPesan
cetakPesan(i, pesan)
}
}
fun cetakPesan(idx: Int, pesan: String) {
println(" [$idx] $pesan")
}Output yang Dihasilkan:
=== Demo Step-Through Debugging ===
Hasil urut: [1, 2, 3, 5, 8, 9]
Statistik: min=1, max=9
[1] Halo
[2] Halo
[3] HaloStep Over vs Step Into #
Step Over mengeksekusi baris saat ini secara penuh, termasuk semua method yang dipanggil di baris tersebut, tanpa kita masuki. Operasi ini cocok untuk method library yang sudah teruji seperti listOf, sorted, atau println. Step Into sebaliknya: bila baris memanggil method, debugger masuk ke method tersebut baris pertama. Operasi ini cocok untuk method yang kita curigai sebagai sumber bug.
Step Out #
Step Out melanjutkan eksekusi sampai method saat ini selesai, lalu berhenti di baris pemanggil. Operasi ini berguna bila kita sudah Step Into terlalu dalam dan ingin keluar. Misalnya setelah Step Into ke cetakPesan di dalam loop ulangiPesan, Step Out akan menyelesaikan cetakPesan dan berhenti kembali di baris pemanggil dalam loop.
Drop Frame #
Drop Frame adalah fitur kurang dikenal namun sangat berguna. Operasi ini membatalkan frame teratas dari call stack, sehingga debugger kembali ke method pemanggil seolah-olah pemanggilan method belum terjadi. State yang sudah diubah tidak otomatis di-rollback — variabel var yang sudah dimodifikasi tetap memuat nilai barunya. Namun kita dapat mengulang pemanggilan method dengan parameter yang sama atau berbeda.
Referensi Lanjutan #
- IntelliJ IDEA Debugging — panduan resmi step-over, step-into, dan step-out di IntelliJ IDEA
Penutup #
Empat operasi step tersebut, dipadukan dengan breakpoint dari chapter sebelumnya, memberi kontrol penuh atas alur eksekusi. Pada chapter berikutnya kita akan beralih dari debugging interaktif ke observasi pasif: mencatat jejak eksekusi melalui logging, yang tetap berguna di lingkungan produksi di mana IDE debugger tidak tersedia.