IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

4. diel - IntelliJ IDEA - Debugging

V minulej lekcii, IntelliJ IDEA - Scopes, Live Templates, Databáza, Pluginy , sme si ukázali Scopes, live templates, SQL Explorer a pluginy.

V dnešnom Java tutoriálu si vysvetlíme, ako debugovať Java aplikácie za pomocou IDE IntelliJ IDEA. Všetko si vyskúšame na jednoduchom príklade.

Debugging

Debugging je proces odstránenie chýb v programe, ktoré obvykle nie sú na prvý pohľad vidieť. Niekedy sa o ňom hovorí aj ako o "ladenie" programu.

Prečo a kedy debugovať?

Chyby v programe sa väčšinou prejavujú tým, že je v nejakej premennej nesprávna hodnota, ktorá potom zapríčiní nefunkčnosť programu. Určite ste sa už dostali do situácie, keď váš program nefungoval správne. Možno ste vykonávali nejaké zdĺhavé kontrolné výpisy rôznych premenných, aby ste zistili, kde je ešte všetko správne a kde sú už nesprávne hodnoty.

Chybu možno ale zvyčajne nájsť oveľa ľahšie pomocou debugovania. Program zvyčajne spustíme v špeciálnom režime, kde máme dovolené určité "cheaty", ako napr. Program pozastavovať a nazerať do obsahu premenných. Práve to sa dnes naučíme.

Nie je však pravda, že debugger používame len keď program nefunguje! Naopak, používame ho čo najviac to ide a to aj napríklad pre kontrolu správnosti na kritických miestach.

Príklad - Krokovanie cyklu

Majme jednoduchý cyklus, v ktorom budeme vypisovať čísla od 0 do 9:

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        System.out.println("Číslo: " + i);
    }
}

Ako si môžete skúsiť, program funguje korektne. Napriek tomu si ho skúsime oddebugovat, než sa pustíme na nefunkčné kód.

Hraničnými

Breakpoint je základný stavebný kameň pri debugovania. Je to "bod" označujúce riadok, na ktorom sa program zastaví. Nám, ako programátorom, sa v tej chvíli zobrazí kompletná kontext programu, teda napr. Čo je v tej chvíli kde uložené. Pretože program stojí, môžeme si všetko ľahko skontrolovať.

Pridanie Breakpoint

Teraz sa naučíme vkladať hraničnými a zastavovať na nich program. V IntelliJ sa breakpoint na daný riadok vkladá kliknutím do priestoru vľavo vedľa čísla riadku. Breakpoint potom spoznáme podľa červeného kolieska. Vložme teda breakpoint na riadok, kde sa vypisuje číslo do konzoly:

Breakpoint - IntelliJ IDEA / NetBeans / Eclipse - Pokročilá práce

Debug režim

Breakpoint máme pridaný. Keď však program teraz spustíme, nič zvláštneho sa nestane. Aby sa program naozaj zastavil, je potrebné ho spustiť v špeciálnom debugovacím režime. K tomu slúžia špeciálne tlačidlo vedľa tlačidla "Play":

Tlačidlo pre debug - IntelliJ IDEA / NetBeans / Eclipse - Pokročilá práce

Klikneme na tlačidlo pre debug. Program sa spustí a až narazí na náš breakpoint, tak sa zastaví:

Debuggovací okno - IntelliJ IDEA / NetBeans / Eclipse - Pokročilá práce

Červený puntík označujúce breakpoint sa zmenil na zelený. To znamená, že breakpoint je dosiahnuteľný.

Záložka Debug

Otvorila sa nová záložka nazvaná Debug, ktorá obsahuje veľké množstvo informácií. Poďme si popísať, čo vidíme:

  • časť ohraničená na obrázku vyššie zelene obsahuje zoznam všetkých aktuálne viditeľných premenných a ich hodnoty; hodnoty je možné zmeniť,
  • oranžovo ohraničená časť obsahuje zásobník volaní všetkých funkcií, ktoré sa zavolali pred Breakpoint

Všimnite si, že IntelliJ sa snažia vkladať hodnoty premenných priamo do editora. V našom prípade vidíme priamo výpis hodnôt poľa.

Ďalej sú na obrázku zvýraznené dve časti ohraničené červeno.

Ovládanie programu a Breakpoint

V ľavej ohraničené červenej časti sa nachádza tlačidlá pre kontrolu ovládanie programu a Breakpoint:

  1. rerun 'Main' Ctrl + F5 - Ukončí aktuálny program a znova ho spustí,
  2. modify run configuration - Zobrazí nastavenia pre debug,
  3. resume program F9 - Uvoľní program z Breakpoint a nechá program bežať a prípadne sa zastaví o ďalšie breakpoint,
  4. pause program - Pozastaví vykonávanie vybraného vlákna - funguje podobne ako breakpoint, iba sa nezobrazia žiadne premenné,
  5. stop 'Main' Ctrl + F2 - Ukončí aktuálny program,
  6. view breakpoints Ctrl + Shift + F8 - pozrite si zoznam všetkých Breakpoint,
  7. mute breakpoints - potlačí všetky hraničnými; Keď program narazí na breakpoint v debug móde, breakpoint bude ignorovaný.
Krokovanie

V druhej červeno ohraničené časti sa nachádza tlačidlá pre krokovanie programu. Pomocou krokovanie môžeme nechať program pokročiť na ďalší riadok a zas sa zastaviť:

  1. step over F8 (krok cez) - Vykonáme ďalší krok cez danú riadku s Breakpoint, na ktorej program aktuálne stoja. Ak sa na riadku volá funkcie, necháme ju len vykonať a potom prejdeme na ďalší riadok
  2. step into F7 (krok do) - Vykonáme ďalší krok "do" danej riadky. Robí to isté čo Step over až na rozdiel, že ak sa na riadku volá funkcie, prejdeme na prvý riadok vo funkcii
  3. force step into Alt + Shift + F7 (vynútený krok do) - Vynúti prechod do funkcie na riadku aj v prípade, že sa nejedná o našu metódu.
  4. step out Shift + F8 (krok von) - Pomocou kroku von vystúpime z aktuálne vykonávané funkcie

My sa nachádzame v cykle, kde iba vypisujeme jednu hodnotu. Keď sa pozrieme do výpisu konzoly, zatiaľ neuvidíme žiadny výpis (okrem možných hlášok od IDE).

Stlačením tlačidla krok cez sa vypíše do konzoly prvé číslo a my sa v programe dostaneme na riadok s for cyklom. Keď tlačidlo stlačíme znovu, uvidíme, že sa inkrementovala pomocná premenná i z hodnoty 0 na hodnotu 1. Týmto spôsobom si môžeme odkrokovat celý cyklus:

Debugging - IntelliJ IDEA / NetBeans / Eclipse - Pokročilá práce

Príklad - debugovania programu

Nakoniec si dáme príklad naozaj k precvičenie debugovania. Máme dva vnorené cykly, ktoré by mali vypísať malú násobilku:

public static void main(String[] args) {
    for (int j = 1; j <= 10; j++) {
        for (int i = 1; j <= 10; j++) {
            System.out.print(i * j + "\t");
        }
        System.out.println();
    }
}

Výsledok by mal vyzerať takto:

Konzolová aplikácia
1   2   3   4   5   6   7   8   9   10
2   4   6   8   10  12  14  16  18  20
3   6   9   12  15  18  21  24  27  30
4   8   12  16  20  24  28  32  36  40
5   10  15  20  25  30  35  40  45  50
6   12  18  24  30  36  42  48  54  60
7   14  21  28  35  42  49  56  63  70
8   16  24  32  40  48  56  64  72  80
9   18  27  36  45  54  63  72  81  90
10  20  30  40  50  60  70  80  90  100

Problém ale je, že sa vypíšu len čísla od 1 do 10:

Konzolová aplikácia
1   2   3   4   5   6   7   8   9   10

Chybu budeme samozrejme chcieť nájsť a opraviť za pomoci Breakpoint a krokovanie. Aj keď uvidíte chybu na prvý pohľad, neotáľajte a tiež si to odkrokujte! V zložitejších aplikáciách chyba ľahko vidieť nebude a debugovania bude potrebné.

Postup riešenia

Očakávame, že vonkajšie cyklus sa vykoná 10x, zatiaľ čo vnútorná cyklus sa vykoná celkom 100x. Vložíme breakpoint na riadok s vonkajším for cyklom:

for (int j = 1; j <= 10; j++) {

A spustíme program v debug režime. Bude nás zaujímať, ako sa premenné i a j zvyšujú. Tlačidlom krok do budeme postupne prechádzať cez oba cykly a pozorovať premenné i a j. Vonkajší cyklus pracuje s premennou j, ktorá by sa mala zmeniť iba 10x. Vnútorné cyklus pracuje s hodnotou i, ktorá by sa mala pri každej zmene j upraviť 10x.

Postupným krokovaním však zistíme, že vnútorný cyklus inkrementuje premennú j namiesto i. Vo vnútornom cyklu upravíme j++ na i++ a program opäť spustíme v debug režime:

for (int i = 1; j <= 10; i++)

Krokom opäť tlačidlom krok do. Sledujeme premennú i. Po čase začne nadobúdať neočakávaných hodnôt, ktoré sa neustále o jednotku zvyšujú. Ak teraz necháte program bežať, začne sa vám počítač kosiť. To je z dôvodu, že vo vnútornom cykle je podmienka, ktorá nikdy nebude splnená.

V cykle for (int i = 1; j <= 10; i++) máme premennú i, ktorú už správne inkrementuje, ale podmienka je zlá. Premenná i sa inkrementuje, kým platí j <= 10. Táto podmienka nikdy nebude splnená, pretože premenná j sa modifikuje len vo vonkajšom cykle. Opravíme podmienku vnútorného cyklu z j <= 10 na i <= 10 a program už spustíme bez Breakpoint:

public static void main(String[] args) {
    for (int j = 1; j <= 10; j++) {
        for (int i = 1; i <= 10; i++) {
            System.out.print(i * j + "\t");
        }
        System.out.println();
    }
}

Výsledkom už je očakávaná malá násobilka:

Konzolová aplikácia
1   2   3   4   5   6   7   8   9   10
2   4   6   8   10  12  14  16  18  20
3   6   9   12  15  18  21  24  27  30
4   8   12  16  20  24  28  32  36  40
5   10  15  20  25  30  35  40  45  50
6   12  18  24  30  36  42  48  54  60
7   14  21  28  35  42  49  56  63  70
8   16  24  32  40  48  56  64  72  80
9   18  27  36  45  54  63  72  81  90
10  20  30  40  50  60  70  80  90  100

V ďalšej lekcii, IntelliJ IDEA - Pokročilý debugging , si rozšírime znalosti debugovania v IntelliJ IDEA.


 

Predchádzajúci článok
IntelliJ IDEA - Scopes, Live Templates, Databáza, Pluginy
Všetky články v sekcii
IntelliJ IDEA / NetBeans / Eclipse - Pokročilá práce
Preskočiť článok
(neodporúčame)
IntelliJ IDEA - Pokročilý debugging
Článok pre vás napísal Petr Štechmüller
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity