Vead
Java on kompileeritud keel, mis võimaldab kompilaatoril suure osa probleemidest tuvastada enne programmi käivitamist, sest kompileerimisvigadega programmi ei saa käivitada.
Koodi kirjutades tuleks programmeerijal arvestada erinevate eriolukordadega, mis võivad programmi käivitamisel või kompileerimisel tekkida. Töökindel programm suudab erinevate olukordadega toime tulla ilma, et jookseks kokku.
Näiteks:
int[] numbers = {0, 1, 2, 3};
System.out.println(numbers[6]); // java.lang.ArrayIndexOutOfBoundsException
System.out.println(numbers[-6]); // java.lang.ArrayIndexOutOfBoundsException
int n = Integer.parseInt("Some text"); // java.lang.NumberFormatException
String noValue = null;
noValue.length(); // java.lang.NullPointerException
Tekkinud tõrked jagunevad kaheks:
Vigadeks (
java.lang.Error
), mis tähistavad üldiselt tõsiseid probleeme, mille tekkimisel programm tööd jätkata ei saa.Erinditeks (
java.lang.Exception
), mis tekivad enamasti loogikavigade tõttu. Kõik ülaltoodud näited on erindid. Erindeid on võimalik ka ise tekitada, näiteks kui soovitakse mõnd veasituatsiooni parandada.
Põhjused
Koodi või andmete viga - nt. vale tüübiteisendus, massiivi sobimatu indeksi kasutamine, avaldises nulliga jagamine jpm.
Vead standardmeetodite kasutamisel - nt. kui kasutada
substring()
meetodit sõne töötlemisel, võime saada vea (erindiklassi) StringIndexOutOfBoundsException.Ise tekitades - Mittesobiva olukorra avastamisel programmi töö käigus, näiteks soovitakse arvelt rohkem raha välja võtta kui seal on.
Java vead - Tekivad JVM-s, mis käivitab kasutaja kompileeritud programmi.
Ennetamine
Mõni koodilõik vajab teatud tingimuste täitmist selleks, et korrektselt töötada.
int[] numbers = {0, 1, 2, 3};
int i = 4;
if (i < 0 || i >= numbers.length) {
// Do something to handle the out-of-range index
System.out.println("Bad index");
} else {
System.out.println(numbers[i]);
}
Sellisel juhul on käsu System.out.println(numbers[i]);
eeltingimuseks (i < 0 || i >= numbers.length)
Stack trace
Tavaliselt programmi tööle pannes jooksutab Java virtuaalmasin järjest meetodeid, alustades main meetodist. Meetodit jooksutades lisatakse see nö kuhja (ik stack). Juhul kui terve meetod on jooksutatud, eemaldatakse see kuhjast, et lisada sinna järjekorras järgmine meetod.
Näiteks:
public class Main {
public static void main(String[] args) {
System.out.println("Starting main method")
m1();
System.out.println("End main method");
}
static void m1() {
System.out.println("Method One - m1");
m2();
}
static void m2() {
System.out.println("Method Two - m2");
}
}
Meil on nüüd main meetod ja kaks teist meetodit - m1 ja m2. Kui programm oma tööd alustab, siis main meetod on kuhjas kõige kõrgemal. main meetodi sees kutsutakse aga välja m1 meetod. Kui see meetod välja kutsutakse, läheb ta kuhja tippu. m1 meetod kutsub välja m2 meetodi, mis läheb omakorda kuhja tippu. Siis kui m2 lõpetab töö, annab ta kontrolli tagasi m1 meetodile ja eemaldatakse kuhjast. Kui m1 lõpetab töö, siis annab ta kontrolli tagasi main meetodile ja omakorda eemaldatakse kuhjast.
Programmi väljund:
Starting main method
Method One - m1
Method Two - m2
End main method
Kui meetod m2 sees peaks tekkima viga, siis otsib Java virtuaalmasin veatöötlust, näiteks try ... catch blokki. Kui selles meetodis veatöötlus puudub, siis otsitakse seda m1 meetodist. Kuna aga m1 blokis see puudub, siis otsitakse omakorda main meetodist. Kui aga lõpuks ka main meetodis puudub veatöötlus, visatakse veateade.
Näiteks muutes meetodit m2:
public class Main {
public static void main(String[] args) {
System.out.println("Starting main method");
m1();
System.out.println("End main method");
}
static void m1() {
System.out.println("Method One - m1");
m2();
}
static void m2() {
int x = 10;
int y = 0;
double z = x / y;
System.out.println(z);
System.out.println("Method Two - m2");
}
}
Sellisel juhul on meetodis m2 nulliga jagamise viga. Programmi käivitades saame väljundiks:
Starting main method
Method One - m1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.m2(Main.java:17)
at Main.m1(Main.java:11)
at Main.main(Main.java:5)
Process finished with exit code 1
Seda kutsutakse kui stack trace. Read 4-6 osutavad meetoditele ning näitavad ridu kust neid leida võib. Kõige ülemine neist näitab, kus esmalt viga tekkis (meie näites meetod m2). Teised read näitavad ülejäänud kuhja, üldiselt lõpetades main meetodiga.