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:
- Erindi tüüp ja sõnum -
ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3 - Esimene rida kus viga tekkis:
at StackTraceExample.method3 line 16 - Teine rida kus viga tekkis:
at StackTraceExample.method2 line 11 - Kolmas rida kus viga tekkis:
at StackTraceExample.method1 line 7 - 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õimesjava.lang.ArrayIndexOutOfBoundsException- erindi tüüpIndex 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:
main()lisatakse virnamain()kutsubmethod1()- lisatakse virnamethod1()kutsubmethod2()- lisatakse virnamethod2()kutsubmethod3()- lisatakse virnamethod3()sees tekib viga- 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.