Java programozás/A nyelv jellemzői
A Java nyelv létrehozásakor négy fő céljuk volt az alkotóknak:
- legyen objektum orientált
- legyen platform független
- tartalmazzon nyelvi elemeket és osztálykönyvtárakat a hálózatkezelés támogatására
- távoli forrásból is biztonságosan lehessen futtatni a kódokat
Objektum orientáltság
szerkesztésAz objektum orientáltság egy programozási szemléletmód és egy nyelvi jellemző. Fő gondolata az, hogy a tervezés középpontjában azok a "dolgok" (azaz objektumok) álljanak, amikkel a program dolgozik, és ne a műveletek, amiket végrehajt.
A hardver eszközök fejlődésével egyre nőtt az igény olyan programozási technológiák iránt, amelyekkel összetettebb alkalmazások készíthetők. Olyan szoftver projekteket szeretnénk létrehozni, amelyeket könnyebb irányítani, átlátni, így javul a szoftverek minősége, és csökken a sikertelen projektek száma. Az objektum orientáltság az egyik legújabb ilyen technológia, de voltak korábbi próbálkozások is.
- Assembly nyelvek
- Az első szoftverfejlesztési technológiák olyan nyelveket használtak, amik közel álltak a gépi kódhoz, így könnyű volt belőlük futtatható kódot készíteni. Minden hardvernek megvolt a saját assembly nyelve. Ezek olyan alacsony szintű utasításokat tartalmaztak, mint például adat mozgatása a memóriából egy regiszterbe, aritmetikai műveletek elvégzése, az adat visszamozgatása a memóriába. A programozóknak ismerniük kellett az adott számítógép architektúráját, hogy programozhassák azt.
- Procedurális nyelvek
- Az assembly nyelvek után magasabb szintű nyelveket fejlesztettek ki. Itt fordítóprogramokat használtak a gépi kódú program létrehozására, így a programozóknak nem kell pontosan ismerniük a számítógép architektúráját. A kód újrafelhasználásának segítésére, és a GOTO utasítás használatának csökkentésére eljárásokat hoztak létre. Ez egyszerűsítette a szoftver irányításának kifejlesztését és karbantartását, de nem foglalkozott az adatok kezelésének szervezésével. Egy rémálom volt hibákat keresni olyan programokban, amikben rengeteg globális változó volt. Ezek olyan adatot tartalmaztak, amelyek a program bármely részéről elérhetők és módosíthatók voltak.
- Objektum orientált nyelvek
- Az ilyen nyelvekben az adatokkal komolyan foglalkozunk az adat elrejtés révén. Az eljárások helyét az objektumok vették át, ezek tartalmazzák az adatokat és az ezekkel dolgozó metódusokat. Eljárások helyett az objektumok közötti kapcsolatok, kölcsönhatások állnak a gondolkodásunk középpontjában.
Platform függetlenség
szerkesztésA platform függetlenség azt jelenti, hogy a Java nyelven írt programoknak hasonlóan kell futniuk különböző architektúrájú hardvereken és operációs rendszereken. Ha egy programot egyszer megírunk valahol, akkor az mindenhol futtatható. Ezt úgy lehet elérni, hogy a Java nyelvű kódot egy köztes nyelvre, az ún. bájtkódra fordítjuk le, ami virtuális gépi utasításokból áll. Ezt a kódot ezután egy Java virtuális gépen futtatjuk, ami egy olyan program, ami az adott számítógép gépi kódjára van lefordítva, a feladata pedig az, hogy a Java bájtkódú utasításokat a helyi gépen használható utasításokra fordítsa le. Ezen kívül rendelkezésre állnak olyan szabványos osztálykönyvtárak, amelyekkel egységes módon ki tudjuk használni a helyi gép tulajdonságait, szolgáltatásait (pl. grafika, hálózatkezelés, többszálúság).
A nyelv első megvalósításai interpretált (értelmezett) virtuális gépeket használtak a hordozhatóság megvalósítására, és még ma is sok ilyen létezik. Ebben az esetben futási időben történik meg a bájtkódú és a gépi kódú utasítás megfeleltetése. Ezek a megvalósítások olyan programokat hoztak létre, amik sokkal lassabban futottak, mint a teljesen lefordított programok, így a Java nyelvről az terjedt el, hogy lassú. A mai Java Virtuális Gépek viszont olyan technikákat használnak, amelyekkel a programok gyorsabban futtathatók.
Az első és legegyszerűbb ezek közül a közvetlenül gépi kódra fordítás, amikor a hagyományos fordítókhoz hasonlóan egyáltalán nem használunk köztes bájtkódot. Ezzel nagyszerű teljesítményt lehet elérni, de ennek az az ára, hogy elveszítjük a hordozhatóság előnyeit. Emiatt ez technika nem terjedt el széleskörűen.
Egy másik lehetőség az ún. just-in-time (JIT) fordítás, amikor rögtön a program indulásakor elkészül a bájtkódból a natív kódú program, és ezt a lefordított kódot újra és újra felhasználjuk. A még kifinomultabb virtuális gépek a dinamikus fordítást is használhatják, amikor elemzik a futtatandó program viselkedését, és csak azokat a részeket fordítják le, amikre ténylegesen szükség van, a legkritikusabb részeket esetleg a lehető legjobban optimalizálva. Mindkét technikával kihasználható a natív kód sebessége anélkül, hogy elveszítenénk a hordozhatóság előnyeit.
Láthatjuk, hogy a hordozhatóság kivitelezése meglehetősen bonyolult, és hogy a Java platformnak ezt mennyire sikerült megvalósítania még ma is vita tárgyát képezi. Valóban tudunk olyan programokat írni, amik nagyon sok platformon ugyanúgy futnak, azonban rengeteg platform van, és ezek hibái és különbözőségei gondot okozhatnak. Talán ez vezetett oda, hogy a Sun "Írd meg egyszer, futtasd bárhol" ("Write once, run anywhere") jelmondatának megszületett a paródiája: "Írd meg egyszer, javítsd mindenhol" ("Write once, debug everywhere").
A távoli kód biztonságos futtatása
szerkesztésA Java platform az első olyan rendszerek egyike volt, ami támogatta a távoli helyen lévő kódok futtatását. A nyelv tervezésekor nagy figyelmet szenteltek a hálózatkezelésnek.
Egy applet futhat a felhasználó böngészőjében egy olyan kódot végrehajtva, amit egy távoli HTTP szerverről töltött le. Ez a távoli kód egy szigorúan felügyelt és korlátozott környezetben, egy ún. homokozóban fut, így védve a felhasználót a hibásan működő vagy rosszindulatú programoktól. A szerző digitálisan aláírhatja az appletjét, így jelezve, hogy az biztonságos, ezzel a program olyan jogokat kaphat, amivel átlépheti a homokozó kereteit, és például elérheti a helyi fájlokat, használhatja a hálózatot.
Értékelés
szerkesztésSokak véleménye szerint a Java technológia jól meg tudta valósítani a kitűzött céljait. De természetesen ennek a nyelvnek is vannak hátrányai.
A Java sok tekintetben magasabb szintű, mint más hasonló nyelvek (pl. C++), ami azt jelenti, hogy hiányoznak belőle olyan eszközök, mint a hardver specifikus típusok, alacsony szintű mutatók a memória bármely részére, vagy az olyan nyelvi elemek, mint az operátor túlterhelés (operator overloading). Habár ezeket könnyű hibásan használni, és sok probléma okozói lehetnek, nagyon is hatékony eszközök. Részben megoldás erre a kérdésre a Java Native Interface (JNI), amivel natív kódú hívásokat tehetünk a Java nyelvű kódunkba. Ezzel néhány fenti tulajdonság használhatóvá válik.
Sok programozó hiányolja a többszörös öröklődést, ami több objektum orientált nyelv hatékony tulajdonsága. A Java azonban elkülöníti a típus definíciójának és megvalósításának öröklődését. Az interfészeken keresztül engedélyezi a típusdefiníciók többszörös öröklődését, de a megvalósítások csak egyszeresen örököltethetők. Ezzel kihasználható a többszörös öröklődés számos előnye, sok veszélye pedig elkerülhető. Ezen kívül a teljes és absztrakt osztályok valamint az interfészek segítségével a Java programozó eldöntheti, hogy az adott típust definiáló osztályt teljesen, részben vagy egyáltalán nem valósítja meg, ezzel biztosítva a szoftvertervezés maximális rugalmasságát.
Hallani olyan véleményeket is, hogy bizonyos projektek esetén az objektum orientáltság nem könnyíti, hanem nehezíti a munkát. Ez a probléma azonban nem csak a Java nyelvre vonatkozik, hanem az összes objektum orientált programozási nyelvre.