Elméleti alapozás
A lehetséges programozási hibák
Java-kódok programozása során lényegében kétféle hibát tudunk elkövetni:
-
szintaktikai hibát,
-
szemantikai hibát.
A szintaktikai hiba során a nyelv FORMAI szabályai ellen vétünk.
Ezt általában egyetlen fordító sem tűri, mert az utasítások pontos végrehajtásához pontos és egzakt bemeneti adatok, valamint hibátlan futtató program szükséges. Sokféle formai hiba létezik, egy tipikus Java-hiba például, ha nem teszünk az utasítás végére lezáró jelet (;).
Helytelenül:
System.out.println("Java")
Helyesen:
System.out.println("Java");
A szemantikai hiba során a nyelv TARTALMI szabályai ellen vétünk.
Némely szemantikai hibát könnyű észrevenni, vannak azonban olyan rejtett hibák, amelyek detektáláshoz ismernünk kell a Java-nyelv belső működését, illetve esetlegesen a mögötte lévő matematikát. Ilyenkor a hibajelenség pusztán az, hogy vagy rossz végeredményeket kapunk vagy a fordító (piros x-szel jelölt) hibát jelez.
Talán a legtipikusabb szemantikai hiba a nullával való osztás (például 7 / 0), amelytől -ha a hiba nincs programozás-technikailag lekezelve-, a fordító azonnal fejre áll. Azt gondolhatjuk, hogy a szabály ismeretében könnyű a hibát elkerülnünk, ám egy sokváltozós, több elágazásos és iterációs függvényben, amelyben a változók értékei gyorsan változhatnak, nagyon hamar belecsúszhatunk ebbe és ehhez hasonló hibába.
Az alábbi egyszerű, futtatható Java-kódban generálunk egy ilyen jellegű hibát. Az alapművelet szerint 1 és 100 közötti véletlenszámokat osztunk el az iteráció számlálójával (i), még pedig tízszer. 9-ről indul a számláló, ám elkövetjük a hibát, hogy az iterációs tartomány legalsó számának 0-t veszünk (i >= 0), ezáltal azonban minden 10. lépés 0-val való osztás lesz.
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random rnd = new Random();
int veletlenszam = 0;
double eredmeny = 0;
for(int i = 9; i >= 0; i--){
veletlenszam = rnd.nextInt(100) + 1;
eredmeny = veletlenszam / i;
System.out.println(eredmeny);
}
}
}
Végeredmény:
Exception in thread "main" java.lang.ArithmeticException: / by zero at Main.main(Main.java:10)
A fordító érzékeli a hibát és azonnal hibaüzenetet (úgynevezett kivételt - exception) küld, sőt a hiba helyét (Main.java:10) és jellegét (java.lang.ArithmeticException: / by zero) is meghatározza.
Hála azonban napjaink fejlesztői programjainknak, a szintaktikai és szemantikai hibák detektálása és megoldása rendkívül magas szintű, legalábbis én folyamatosan ezt tapasztalom az ingyenes Eclipse nevű platform használata során. Az Eclipse a hibát az aktuális sor mellett megjelenített piros x jellel jelzi, sőt a kurzort a jel fölé mozgatva a hiba jellegéről is értesít (legtöbbször értelmesen). A legtöbb hibát akkor is felismeri, ha forrása egy másik, valamilyen módon kapcsolt kódrészletben van. Emellett számos további olyan szolgáltatással rendelkezik, amely még inkább megkönnyíti a szoftverfejlesztés fáradságos lépéseit.
A rendkívül magas szintű hibakiértékelés azonban bár megkönnyíti, de nem helyettesítheti a programozó gyakorlati tapasztalatait.
Végső soron a programozó dönti el, hogy a bemeneti adatok és a megírt program helyes kimeneti adatokat produkálnak-e (azaz mindig vannak elvárt eredmények - expected results). S bár ez is automatizálható tesztfüggvények bevetésével, a végső döntés, a „kiértékelés kiértékelése” mégiscsak a programozó feladata.
A jelen fejezet alapszinten csakis a szintaktikai és szemantikai hibákat ismerteti. Szintén hibaként értékelendő, de általánossága miatt bővebben nem foglalkozunk azon hibaesetekkel, amikor a programozó vagy programtervező rosszul értelmez valamit a specifikációban és úgy is kódolja le. Ez sem szintaktikai, sem szemantikai, hanem értelmezésbeli hiba. Javítása legtöbbször csakis a kérdéses kód teljes újraírásával lehetséges.