Liigu peamise sisu juurde

Veateated Javas

Sissejuhatus

Programmeerimisel tekivad vead paratamatult. Mõned vead avastab kompilaator juba enne programmi käivitamist (nt süntaksivead), kuid osa vigu ilmnevad alles programmi töö ajal. Selliseid käivitusaegseid vigu nimetatakse erinditeks (exceptions). Kui programm satub olukorda, mida ta ei oska korrektselt lahendada, viskab Java erindi ning kuvab veateate koos pinu jäljega (stack trace).

Veateade sisaldab infot:

  • mis tüüpi viga tekkis,
  • milline oli veateade,
  • millises failis ja real viga tekkis,
  • milline oli meetodite väljakutsete jada enne vea tekkimist.

Veateadete lugemise oskus on programmeerimisel üks olulisemaid praktilisi oskusi.

Näide veast ja veasõnumist

Vaatame lihtsat näidet programmist, kus tekib käivitusaegne viga. Antud näites kutsuvad meetodid üksteist järjest välja. Lõpuks proovib method3() lugeda massiivist elementi, mis jääb massiivi piiridest välja:

public class StackTraceExample {
public static void main(String[] args) {
method1();
}

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

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

public static void method3() {
int[] arr = {1, 2, 3};
System.out.println(arr[10]); // Error!
}
}

Massiivis on ainult 3 elementi (indeksid 0, 1 ja 2), kuid programm üritab lugeda indeksit 10. Selle tulemusena viskab Java erindi ArrayIndexOutOfBoundsException ning väljastab pinu jälje.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3
at StackTraceExample.method3(StackTraceExample.java:16)
at StackTraceExample.method2(StackTraceExample.java:11)
at StackTraceExample.method1(StackTraceExample.java:7)
at StackTraceExample.main(StackTraceExample.java:3)

Pinu jälg näitab:

  • millises meetodis viga tegelikult tekkis,
  • milliste meetodite kaudu sinna jõuti,
  • milline oli programmi alguspunkt.

Selline info võimaldab arendajal kiiresti leida vea täpse asukoha ja põhjuse.

Veateate lugemine

Veateateid loetakse ülevalt alla:

  1. Erindi tüüp ja sõnum - ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3
  2. Esimene rida kus viga tekkis: at StackTraceExample.method3 line 16
  3. Teine rida kus viga tekkis: at StackTraceExample.method2 line 11
  4. Kolmas rida kus viga tekkis: at StackTraceExample.method1 line 7
  5. Neljas rida on programmi algus: at StackTraceExample.main line 3

1. Erindi tüüp ja sõnum

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3
  • Exception in thread "main" - viga tekkis peamises lõimes
  • java.lang.ArrayIndexOutOfBoundsException - erindi tüüp
  • Index 10 out of bounds for length 3 - vea kirjeldus

2. Meetodite jada

at StackTraceExample.method3(StackTraceExample.java:16)
at StackTraceExample.method2(StackTraceExample.java:11)
at StackTraceExample.method1(StackTraceExample.java:7)
at StackTraceExample.main(StackTraceExample.java:3)

Iga rida sisaldab:

  • Klassi nime: StackTraceExample
  • Meetodi nime: method3, method2, jne
  • Faili nime: StackTraceExample.java
  • Rea number: :16, :12, jne

Nende järgi on võimalik välja juurida, kus viga alguse sai, mis teekonda läbis ning kus see kulmineerus.

Väljakutsete virn (Call stack)

Väljakutsete virn on andmestruktuur, mis hoiab infot aktiivsete meetodite kohta:

Kui programm käivitub:

  1. main() lisatakse virna
  2. main() kutsub method1() - lisatakse virna
  3. method1() kutsub method2() - lisatakse virna
  4. method2() kutsub method3() - lisatakse virna
  5. method3() sees tekib viga
  6. Java genereerib pinu jälje, mis näitab kogu virna sisu

Vea asukoha leidmine

1. Loe esimest rida hoolikalt

Erindi nimi ja sõnum ütlevad tavaliselt täpselt, mis läks valesti:

ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3

Antud juhul üritati massiivist võtta elementi, mis asub indeksil 10, aga massiiv on ainult 3 elementi pikk

2. Vaata esimest at rida

See näitab täpselt, kus viga tekkis:

at StackTraceExample.method3(StackTraceExample.java:16)

Ava StackTraceExample.java fail ja mine reale 16

3. Uuri väljakutsete jada

Kui vea algpõhjus pole esimesel real selge, vaata, kuidas selleni jõuti:

at MyClass.method3(MyClass.java:16)    // First occurence
at MyClass.method2(MyClass.java:11) // Called method3
at MyClass.method1(MyClass.java:7) // Called method2
at MyClass.main(MyClass.java:3) // Entry point

4. Ignoreeri Java sisemisi väljakutseid

Pikad pinu jäljed võivad sisaldada Java sisemisi meetodeid:

at MyClass.myMethod(MyClass.java:10)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.stream.Stream.forEach(Stream.java:...)
at MyClass.main(MyClass.java:5)

Keskendu enda koodi ridadele (MyClass), Java sisemised read (java.base/...) on tavaliselt vihje, millised teegid olid kaasatud.