Professional Documents
Culture Documents
Java programozs
1.3. verzi
2007. februr
2. oldal
Jogi nyilatkozat
Az albbi felttelekkel:
Jelld meg! A szerz vagy a jogosult ltal meghatrozott mdon kell megjellni a mvet (pl. a szerz s a cm feltntetsvel).
Ne add el! Ezt a mvet nem hasznlhatod fel kereskedelmi clokra. A szerzi jogok tulajdonosnak rsos engedlyvel brmelyik fenti feltteltl eltrhetsz. A fentiek nem befolysoljk a szabad felhasznlshoz fzd, illetve az egyb jogokat. Ez a Legal Code (Jogi vltozat, vagyis a teljes licenc) szvegnek kzrthet nyelven megfogalmazott kivonata. Ez a kivonat a http://creativecommons.org/licenses/by-nc/2.5/hu/ oldalon is olvashat. A teljes licensz a http://creativecommons.org/licenses/by-nc/2.5/hu/legalcode oldalon rhet el. E jegyzet hivatalos honlapjrl (http://nagygusztav.hu) tlthet le a mindenkori legfrissebb verzi.
3. oldal
Bevezets
Felhasznls
Ezzel a jegyzettel arra vllalkozok, hogy a Kecskemti Fiskola GAMF Karn tanul mszaki informatikus hallgatk kezbe olyan rsos anyagot adjak, amely az eladsok s gyakorlatok mellett tovbbi segtsget ad a Java nyelv alapjainak s alapvetbb osztlyainak alapos megismersre. A jegyzet hasznlathoz nem nlklzhetetlen, de ersen javasolt az eladsok ltogatsa s a gyakorlatokon val aktv rszvtel. A jegyzet alapveten a tanrk menethez kapcsold lineris feldolgozsra kszlt, de a fejezetek egy rsze nem pt a kzvetlen megelz fejezetekre. Az egyes fejezetek tananyagnak elsajttshoz az elmleti rsz tolvassa utn az ellenrz krdsek alapos tgondolst, valamint a gyakorl feladatok megoldst javaslom. Enlkl a tantrgy teljestse a hallgatk tbbsge szmra nem lesz eredmnyes. A jegyzet felttelezi a C++ programozsi nyelv minimum kzp szint ismerett. Az anyag elsajttsa ennek hinyban sem lehetetlen, de tbb idt kell rfordtani. A jegyzet alapos ttanulmnyozsa s a Java programozs komolyabb gyakorlsa utn akr a Sun Java programozi minstsnek megszerzsre is lehet kszlni.
Ksznet
A jegyzet elksztshez elssorban a Sun Microsystems Java Tutorial-jt hasznltam. Tovbbi informcikrt a http://java.sun.com oldalt, valamint az ELTE pillanatnyilag nehezen elrhet, de nagyon npszer Java tikalauz programozknak cm knyvt ajnlom. Szeretnk ksznetet mondani a Sun-nak a Java megalkotsrt, a hallgatknak, akik a jegyzet alapjul szolgl Java Tutorial nyers fordtsnak elksztsben rszt vettek, s vgl, de nem utols sorban kollgmnak, Gurka Dezsn Csizms Editnek a jegyzet alapos tolvassrt s pt tleteirt.
Tervek
A tavaszi flv folyamt ellenrz s gyakorl feladatokkal szeretnm a jegyzetet bvteni. Ennek prhuzamosan tvoktatsi jegyzett alakts is meg fog trtnni. Kecskemt, 2007. februr a szerz
4. oldal
Tartalomjegyzk
1.Els lpsek......................................................................................................................... 9 1.1.Az els cssze kv.......................................................................................................9 1.1.1Az els alkalmazs ltrehozsa...............................................................................9 1.2.Bevezets a Java technolgiba.................................................................................11 1.2.1A Java programozsi nyelv...................................................................................11 1.2.2Java platform........................................................................................................12 1.3.Mire j a Java technolgia?.......................................................................................12 1.4.Mg egyszer a HelloWorld programrl.....................................................................13 1.4.1Megjegyzsek a Java nyelvben.............................................................................13 1.4.2Osztlydefinci....................................................................................................14 1.4.3A main metdus...................................................................................................14 1.4.4Osztlyok s objektumok hasznlata...................................................................15 1.5.Ellenrz krdsek.....................................................................................................16 2.Objektumorientlt paradigma..........................................................................................17 2.1.Az objektum................................................................................................................17 2.2.Az zenet....................................................................................................................18 2.3.Az osztly.................................................................................................................... 9 1 2.4.Az rklds............................................................................................................... 1 2 2.5.Publikus interfsz......................................................................................................23 2.6.Ellenrz krdsek....................................................................................................23 2.7.Gyakorl feladat........................................................................................................24 3.Vltozk............................................................................................................................25 3.1.Adattpusok................................................................................................................26 3.2.Vltoz nevek.............................................................................................................27 3.3.rvnyessgi tartomny............................................................................................28 3.4.Vltozk inicializlsa...............................................................................................28 3.5.Vgleges vltozk......................................................................................................29 3.6.Ellenrz krdsek....................................................................................................29 4.Opertorok.......................................................................................................................32 4.1.Aritmetikai opertorok..............................................................................................32 4.1.1Implicit konverzi................................................................................................34 4.2.Relcis opertorok...................................................................................................35 4.3.Logikai opertorok....................................................................................................36 4.3.1Rvidzr kirtkels.............................................................................................37 4.4.Bitlptet s bitenknti logikai opertorok..............................................................38 4.4.1Bitmanipulcik a gyakorlatban.........................................................................39 4.5.rtkad opertorok.................................................................................................40 4.6.Egyb opertorok.......................................................................................................41 4.7.Ellenrz krdsek.....................................................................................................41 5.Kifejezsek, utastsok, blokkok......................................................................................43 5.1.Kifejezsek.................................................................................................................. 3 4 5.2.Utastsok..................................................................................................................45 5.3.Blokkok......................................................................................................................46 5.4.sszefoglals.............................................................................................................46 5.5.Ellenrz krdsek....................................................................................................46 5.6.Gyakorl feladatok....................................................................................................47 6.Vezrlsi szerkezetek.......................................................................................................48 6.1.A while s a do-while ciklusok..................................................................................48
5. oldal 6.2.A for ciklus................................................................................................................. 9 4 6.3.Az if-else szerkezet.....................................................................................................51 6.4.A switch-case szerkezet.............................................................................................53 6.4.1A switch utasts s a felsorolt tpus...................................................................54 6.5.Vezrlstad utastsok...........................................................................................55 6.6.Ellenrz krdsek....................................................................................................59 6.7.Gyakorl feladatok....................................................................................................60 7.Objektumok hasznlata...................................................................................................62 7.1.Objektumok ltrehozsa............................................................................................62 7.2.Hivatkozs egy objektum tagjaira.............................................................................66 7.3.Metdushvs............................................................................................................. 6 6 7.4.Nem hasznlt objektumok eltvoltsa.....................................................................67 7.5.Takarts....................................................................................................................67 7.6.Ellenrz krdsek....................................................................................................67 7.7.Gyakorl feladat........................................................................................................68 8.Karakterek s sztringek...................................................................................................69 8.1.A Character osztly....................................................................................................69 8.2.String, StringBuffer s StringBuilder osztly...........................................................70 8.3.Sztringek darabolsa.................................................................................................78 8.4.Ellenrz krdsek....................................................................................................78 8.5.Gyakorl feladatok....................................................................................................80 9.Szmok.............................................................................................................................. 1 8 9.1.A csomagol osztlyok nhny hasznlata............................................................... 81 9.2.Szvegbl szmm konvertls................................................................................83 9.3.Szmbl szvegg konvertls .................................................................................83 9.4.Szmok formzott konvertlsa...............................................................................84 9.5.Aritmetika..................................................................................................................87 9.6.Ellenrz krdsek....................................................................................................90 10.Tmbk........................................................................................................................... 2 9 10.1.Tmbk ltrehozsa s hasznlata..........................................................................92 10.2.Objektum tmbk...................................................................................................94 10.3.Tmbk tmbjei......................................................................................................95 10.4.Tmbk msolsa....................................................................................................96 10.5.Ellenrz krdsek..................................................................................................97 10.6.Gyakorl feladatok..................................................................................................98 11. Osztlyok ltrehozsa..................................................................................................100 11.1.Osztlyok deklarlsa.............................................................................................100 11.2.Tagvltozk deklarlsa.........................................................................................101 11.3.Metdusok deklarlsa..........................................................................................102 11.4.Konstruktorok........................................................................................................103 11.5.Informcitads metdus vagy konstruktor szmra........................................ 104 11.6.A metdusok visszatrsi rtke............................................................................107 11.7.A this kulcssz hasznlata......................................................................................108 11.8.Egy osztly tagjai elrhetsgnek felgyelete .....................................................109 11.9.A pldnyok s az osztly tagok..............................................................................114 11.9.1A pldnyok s az osztly tagok inicializlsa..................................................115 11.10.Ellenrz krdsek................................................................................................116 11.11.Gyakorl feladatok.................................................................................................118 12.rklds......................................................................................................................120 12.1.Metdusok fellrsa s elrejtse...........................................................................120 12.2.Tagvltozk elrejtse..............................................................................................122 12.3.A super hasznlata.................................................................................................122
6. oldal
12.4.Az Object osztly metdusai..................................................................................124 12.5.Vgleges osztlyok s metdusok..........................................................................126 12.6.Ellenrz krdsek.................................................................................................127 12.7.Gyakorl feladatok.................................................................................................128 13.Begyazott osztlyok.....................................................................................................129 13.1.Bels osztlyok ......................................................................................................130 13.2.Nhny tovbbi rdekessg....................................................................................131 13.3.Ellenrz krdsek.................................................................................................132 14.Felsorols tpus.............................................................................................................133 14.1.Ellenrz krdsek.................................................................................................134 15.ltalnos programozs.................................................................................................135 15.1.ltalnos tpus definilsa s hasznlata...............................................................135 15.2.Kapcsolatok az ltalnos tpusok kztt...............................................................136 15.3.Helyettest tpus ................................................................................................... 37 1 15.4.ltalnos metdusok definilsa s hasznlata ...................................................138 15.5.ltalnos tpusok hasznlata az rklsben......................................................... 138 15.6.Ellenrz krdsek.................................................................................................140 16.Interfszek.....................................................................................................................141 16.1.Interfsz definilsa................................................................................................141 16.2.Interfszek implementlsa..................................................................................142 16.3.Az interface hasznlata tpusknt..........................................................................143 16.4.Ellenrz krdsek.................................................................................................143 17.Csomagok......................................................................................................................145 17.1.Csomag ltrehozsa................................................................................................145 17.2.Egy csomag elnevezse...........................................................................................146 17.3.Csomag tagok hasznlata.......................................................................................146 17.4.Forrs s osztly fjlok menedzselse...................................................................148 17.5.Ellenrz krdsek.................................................................................................150 18.Kivtelkezels................................................................................................................152 18.1.Kivtelek elkapsa vagy tovbbengedse.............................................................. 153 18.2.Kivtelek dobsa....................................................................................................159 18.2.1A throw hasznlata...........................................................................................160 18.3.Eldobhat osztlyok s leszrmazottai.................................................................160 18.4.Lncolt kivtelek....................................................................................................161 18.5.Sajt kivtel osztlyok ltrehozsa........................................................................162 18.6.Ellenrz krdsek.................................................................................................163 19.Programszlak kezelse................................................................................................165 19.1.A Timer s a TimerTask osztly.............................................................................166 19.1.1Idztett szlak lelltsa...................................................................................167 19.1.2Ismtelt futtats................................................................................................167 19.2.Szlak pldnyostsa............................................................................................168 19.2.1Thread leszrmazott s a run fellrsa...........................................................168 19.2.2Runnable interfsz pldnyostsa..................................................................170 19.3.Programszl letciklusa.........................................................................................172 19.3.1Programszl ltrehozsa...................................................................................172 19.3.2Programszl elindtsa.....................................................................................172 19.3.3Programszl nem futtathat llapotba lltsa............................................... 173 19.3.4Programszl lelltsa......................................................................................174 19.3.5Programszl sttusz tesztelse.........................................................................175 19.3.6A processzor hasznlatnak feladsa...............................................................175 19.4.Ellenrz krdsek.................................................................................................176 20.Fjlkezels....................................................................................................................178
7. oldal 20.1.Adatfolyamok.........................................................................................................178 20.1.1Fjl adatfolyamok hasznlata .........................................................................182 20.1.2Szr adatfolyamok.........................................................................................183 20.2.Objektum szerializci..........................................................................................186 20.2.1Objektumok szerializlsa...............................................................................186 20.2.2Objektum szerializci a gyakorlatban...........................................................187 20.2.3Az Externalizable interfsz implementlsa..................................................188 20.2.4Az rzkeny informci megvdse................................................................188 20.3.Kzvetlen elrs llomnyok..............................................................................189 20.3.1A kzvetlen elrs llomnyok hasznlata................................................... 190 20.4.Tovbbi osztlyok s interfszek..........................................................................190 20.5.Ellenrz krdsek.................................................................................................191 21.Gyjtemnyek...............................................................................................................193 21.1.A gyjtemny keretrendszer..................................................................................193 21.1.1A Gyjtemny keretrendszer hasznlatnak elnyei.......................................193 21.2.Interfszek..............................................................................................................194 21.2.1A gyjtemny interfszek.................................................................................195 21.2.2A Collection interfsz.......................................................................................196 21.2.3A Set interfsz..................................................................................................198 21.2.4A List interfsz.................................................................................................201 21.2.5Map interfsz...................................................................................................206 21.2.6Objektumok rendezse....................................................................................208 21.3.Implementcik.....................................................................................................212 21.3.1ltalnos cl Set implementcik..................................................................213 21.3.2ltalnos cl List implementcik................................................................214 21.3.3ltalnos cl Map implementcik...............................................................214 21.4.Algoritmusok..........................................................................................................214 21.4.1Rendezs...........................................................................................................214 21.4.2Kevers.............................................................................................................216 21.4.3Keress.............................................................................................................. 16 2 21.5.Ellenrz krdsek.................................................................................................216 22.Hlzatkezels..............................................................................................................218 22.1.Hlzati alapok......................................................................................................218 22.1.1TCP....................................................................................................................218 22.1.2UDP..................................................................................................................218 22.1.3A portokrl ltalnossgban............................................................................219 22.1.4Hlzati osztlyok a JDK-ban.........................................................................220 22.2.URL-ek kezelse....................................................................................................220 22.2.1URL objektum ltrehozsa..............................................................................221 22.2.2URL elemzs....................................................................................................223 22.2.3Kzvetlen olvass URL-bl.............................................................................224 22.2.4Csatlakozs egy URL-hez................................................................................224 22.3.Socketek kezelse..................................................................................................226 22.3.1Mi az a socket?.................................................................................................226 22.3.2Olvass s rs a socket-rl.............................................................................227 23.JDBC adatbzis-kezels...............................................................................................230 23.1.Adatbzis belltsa...............................................................................................230 23.2.Tblk hasznlata..................................................................................................232 23.2.1Tbla ltrehozsa.............................................................................................232 23.2.2JDBC Statement ltrehozsa..........................................................................233 23.2.3SQL parancs vgrehajtsa...............................................................................234 23.2.4Lekrdezsek eredmnynek feldolgozsa.....................................................235
8. oldal
24.Kdolsi konvencik....................................................................................................237 24.1.Fjlok szervezse.................................................................................................... 37 2 24.2.Behzs.................................................................................................................238 24.3.Megjegyzsek........................................................................................................240 24.3.1Implementcis megjegyzsek....................................................................... 240 24.3.2Dokumentcis megjegyzsek........................................................................241 24.4.Deklarcik...........................................................................................................242 24.4.1A deklarci helye............................................................................................243 24.4.2Osztly s interfsz deklarci........................................................................243 24.5.Utastsok..............................................................................................................244 24.6.Elvlasztk............................................................................................................246 24.7.Elnevezsi konvencik..........................................................................................246 25.Tervezsi mintk..........................................................................................................248 25.1.Ltrehozsi mintk................................................................................................249 25.1.1Egyke (Singleton).............................................................................................249 25.1.2Gyrtfggvny (Factory Method) minta.......................................................250 25.2.Szerkezeti mintk..................................................................................................252 25.3.Viselkedsi mintk................................................................................................252 26.Java fejleszteszkzk.................................................................................................253 26.1.JCreator.................................................................................................................. 53 2 26.2.Netbeans................................................................................................................253 26.2.1Alapvet hasznlat...........................................................................................254 26.3.Eclipse.................................................................................................................... 56 2 26.3.1Alap tulajdonsgok..........................................................................................256 26.3.2Az Eclipse beszerzse s zembe helyezse....................................................257
1.Els lpsek
9. oldal
1. Els lpsek
Ez a fejezet a Java programozs alapjaihoz mutat utat. Bemutatja, hogyan tudjuk a Javt beszerezni, s hogyan tudjuk elkszteni, fordtani s futtatni az egyszer Java programokat. Vgl megismerhetjk azt a httrtudst, amely a programok mkdsnek megrtshez szksges.
1.1.
Az els cssze kv
A telepts a Windowsban megszokott egyszersggel trtnik, ltalban elegend a Next gombra kattintani.
Dokumentci
A Java fejlesztkrnyezeten kvl rdemes beszerezni (br a fordtshoz kzvetlenl nem szksges) az API (Application Programming Interface) dokumentcit is (szintn az elz letltsi oldalrl indulva). Ez a Java platformon hasznlhat tbb ezer osztly igen rszletes dokumentcijt tartalmazza. A tmrtett ZIP llomny tartalmt (docs knyvtr) a fejlesztkrnyezet gykrknyvtrba (pl. C:\Program Files\ jdk1.6.0_01) rdemes kicsomagolni.
Szvegszerkeszt
Brmilyen editor megfelel a jegyzettmbtl (Notepad.exe) az sszetett programozi editorokig. Nem rdemes a tanuls legelejn olyan integrlt fejlesztkrnyezet (IDE Integrated Development Environment) alkalmazni, amelyik bizonyos nyelvi elemeket elrejt a programoz ell (pl. JBuilder), ugyanakkor a rendszer rengeteg szolgltatsa kztt elveszik a kezd felhasznl. Elegend a kdkiemelst biztost, esetleg a gpelst knnyt szerkeszt hasznlata is. A nyelvtani alapok, fordts, futtatsi ciklus begyakorlsa utn mr praktikus lehet az tlls egy komolyabb tmogatst nyjt eszkzre. A Jegyzet 25. fejezetben hrom npszer editor hasznlathoz tallnak tippeket. (E fejezet pldi a parancssori fordts-futtats kiss nehzkes mdszert mutatjk be.)
1.1.1
A fejleszts menett jl mutatja a kvetkez bra: a forrsllomnybl a fordts hatsra elll bjtkdot (bytecode) klnbz (Java Virtulis Gpet, JVM-et tartalmaz) opercis rendszeren tudjuk futtatni.
10. oldal
Az els program (HelloWorldApp) egyszeren kirja a kpernyre a Hello World! zenetet. A kvetkez lpsek szksgesek:
Az els programunk:
public class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } }
1.Els lpsek
11. oldal
1.2.1
A Java egy magas szint nyelv a kvetkez fbb jellemzkkel: egyszer objektumorientlt elfordtott rtelmezett robusztus biztonsgos semleges architektrj hordozhat nagy teljestmny tbbszl dinamikus
Megjegyzs: Valsznleg a felsorols egy rsze most mg nem sokat mond. Mire azonban a jegyzet vgre rnek, s a Java nyelv fejlesztsben legalbb alap szint gyakorlatuk lesz, ez a lista sokkal tbbet fog mondani.
A legtbb programozsi nyelv esetn fordtst vagy rtelmezst hajtunk vgre, mieltt a program futna a gpnkn. A Java esetn a kettnek egy klns keverkt hasznljuk. Elszr a forrsprogramot (myProgram.java) a fordt (compiler, bin\javac.exe) egy kzbls nyelvre fordtva Java bjtkdot (myProgram.class) llt el, s ezt a platformfggetlen kdot rtelmezi s futtatja a Java VM (interpreter, bin\java.exe). A fordts egy alkalommal trtnik, az rtelmezs pedig minden alkalommal, ahnyszor a program vgrehajtdik. A kvetkez bra ennek mkdst illusztrlja.
12. oldal
A Java bjtkdot gpi kdd alaktja a Java VM. Minden Java rtelmez, akr a fejlesztkrnyezet, akr egy bngszben fut applet, tartalmaz Java VM-et a futtatshoz. A Java bjtkd segtsgvel megoldhat az, hogy csak egyszer kell megrni egy Java programot, majd tetszleges (megfelel verzij) Java VM-et tartalmaz gpen futtatni lehet. A Java programunkat brmelyik opercis rendszeren teleptett fordtval le lehet fordtani, mindentt hasznlhat lesz.
Megjegyezs: A fordtst s rtelmezst is alkalmaz hibrid megolds manapsg egyre nagyobb npszersgnek rvend. A Microsoft .Net platformja sok architektrlis elemet vett t a Javtl, a web hagyomnyos rtelmez megoldsai ma mr sokszor elfordtssal is kombinlhatk.
1.2.2
Java platform
A platform hardver vagy szoftverkrnyezet, ahol a programok futnak. A legtbb platform a hardvert s az opercis rendszert jelenti. A Java platform annyiban klnbzik a legtbb ms platformtl, hogy teljesen szoftverplatform, s ms hardver alap platformokra pl. A Java platform kt komponensbl ll: Java VM Java API
A Java API igen sok (tbb ezer) hasznlatra ksz szoftverkomponenst tartalmaz: csomagokba szervezett osztlyokat s interfszeket. A kvetkez bra bemutatja a Java platform mkdst.
A natv kd olyan kdot jelent, amelyik a hardveren kzvetlenl futtathat. A platformfggetlen Java kd valamivel lassabb, mint a natv kd. Azonban j fordtval, optimalizlt rtelmezvel, s JIT bjtkd fordtval a klnbsg elg kicsi lehet. A mai futtatkrnyezetek mr tartalmazzk a JIT (Just in time) fordtt, amivel az els futtats eltt natv kdra fordul a bjtkd, gy a tovbbi futsok sorn mr kzvetlenl a natv kd futtathat.
Megjegyzs: Az elzek kvetkezmnye, hogy egy Java alkalmazs els futtatsa tbb ideig tarthat, de a tovbbi futtatsoknl ez az idvesztesg nem fog jelentkezni.
1.Els lpsek
13. oldal
Az asztali alkalmazs olyan program, amely kzvetlenl a Java platformon (pl. nem bngszben) futtathat. Az alkalmazsok specilis fajtja szerverknt fut, hlzati klienseket kiszolglva. Pldul lehet webszerver, proxy-szerver, levelez szerver vagy nyomtat szerver. Szintn specilis program a szervlet (servlet). Szerver oldalon fut, de nem nllan, hanem egy szerver-futtatkrnyezet rszeknt. Pl. egy portlt ki lehet szolglni nhny szervlet egyttesvel, vagy akr egyetlen szervlettel. Ebben az esetben a szervlet a webszerver rszeknt fut. A szervletek hasonlak az appletekhez, mivel futsidej kiterjesztsei a (szerver) alkalmazsoknak. A mobil telefonon, kzi szmtgpen fut alkalmazst midletnek hvjuk. Hogyan nyjtja az API ezt a sokfle tmogatst? Szoftverkomponensek csomagjaiknt, amelyek sokfle feladatot elltnak. A Java platform minden teljes implementcija (pldul a midlet futtatkrnyezet nem teljes) rendelkezik a kvetkez tulajdonsgokkal: Alap sszetevk: objektumok, sztringek, szlak, szmok, I/O, adatstruktrk, dtum s idkezels, stb. Appletek: a szoksos felhasznlsok Hlzatok: URL, TCP, UDP, socket-ek, IP cmzs Nemzetkzi programozs: Segtsg az egsz vilgon hasznlhat alkalmazsok rshoz. A programok knnyedn tudnak alkalmazkodni a helyi sajtossgokhoz, s tbbfle nyelven kommuniklni a felhasznlkkal Biztonsg: alacsony s magas szint vdelem, belertve az elektronikus alrst, titkos-, s nyilvnos kulcs titkostst, hozzfrs-szablyozst s azonostst Szoftver komponensek: a JavaBeans hasznlatval knnyen sszeilleszthet komponenseket fejleszthetnk Objektum szerializci: lehetv teszi a knnysly perzisztencit s az RMI-t JDBC: relcis adatbzis-kezelk szles krhez nyjt egysges elrsi felletet
A Java platform ezen fell tartalmaz API-t a 2D s 3D grafikhoz, szerverekhez, telefnihoz, beszdfeldolgozshoz, animcihoz stb.
14. oldal
Ez egy dokumentcis megjegyzs, a fordt figyelmen kvl hagyja, mint az elz tpust is, de a javadoc eszkz (bin\javadoc.exe) segtsgvel automatikusan lehet generlni hypertext (HTML) dokumentcit, ami felhasznlja a dokumentcis megjegyzseket is.
Megjegyzs: a letlthet Java dokumentci is ez alapjn kszlt.
// szveg
1.4.2
Osztlydefinci
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }
Az osztly (class) alapvet pteleme az objektumorientlt nyelveknek. Az osztly az adatok s viselkedsek sszessgbl ll pldnyok sablonjt adja meg. Amikor az osztlybl pldnyt hozunk ltre, akkor tulajdonkppen egy olyan objektum jn ltre, amelyik gy pl fel, s gy viselkedik, mint az osztly egyb pldnyai. Az adatok az objektumpldnyok vltoziknt rhatk le, a viselkedsek pedig a metdusokkal. A vals letbl egy hagyomnyos plda a tglalap osztly. Az osztly tartalmaz vltozkat a pozci, valamint a szlessg s magassg lersra, s tartalmaz metdust a terlet kiszmtsra. A Java nyelvben a legegyszerbb osztlydefinci a kvetkez:
class name { . . . }
A class kulcsszval s az osztly nevvel kezddik az osztlydefinci, majd kapcsos-zrjelek kztt vltozk s metdusok kvetkeznek. A korbbi plda alkalmazsunkban nincs vltoz, s csak egyetlen metdus van main nven.
1.4.3
A main metdus
public static void main(String[] args)
Minden Java alkalmazsnak tartalmaznia kell main metdust a kvetkez deklarcival: A main metdus deklarcija hrom mdostt tartalmaz: public: jelzi, hogy a metdust ms osztlybeli objektumokbl is meg lehet hvni static: jelzi, hogy a main osztlymetdus void: jelzi, hogy a metdusnak nincs visszatrsi rtke
1.Els lpsek
15. oldal
1.4.4
A pldaalkalmazsunk egy nagyon egyszer Java program, ezrt nincs szksge arra, hogy ms osztlyokat alkalmazzunk, a kpernyre rst kivve. sszetettebb programok hasznlni fognak ms segt osztlyokat. A HelloWorld alkalmazs egyedl a System osztlyt hasznlja. Ez az osztly rendszerfggetlen hozzfrst tesz lehetv a rendszerfgg szolgltatsokhoz. Pldnkban egy osztlyvltoz (out) pldny metdust (println) hvjuk meg.
Ahogy ltszik, a pldnymetdusok s vltozk hasznlata hasonl az osztlymetdusok s vltozk mkdshez. A Java fordt megengedi egy lpsben a tbbszrs hivatkozst:
16. oldal
System.out.println("Hello World!");
Mit tartalmaz a main fggvny paramternek 0. eleme? A program nevt A paramterek szmt Az els paramtert
2.Objektumorientlt paradigma
17. oldal
2. Objektumorientlt paradigma
Az objektumorientlt programozs alapfogalmaival korbban mr bizonyra minden olvas tallkozott. A tma rendkvli fontossga miatt egy rvid bevezetst is olvashatnak ebben a fejezetben. A jegyzet pldi ltalban elg egyszerek, de rdemes minl elbb megismerkedni egy olyan jellsmddal, amivel az objektumorientlt programunkat elre megtervezhetjk. Ler eszkzknt a leginkbb elterjedt UML (Unified Modeling Language 1) jellseivel fog tallkozni a jegyzetben a tisztelt olvas.
2.1. Az objektum
Az objektumok az objektumorientlt technolgia alapjai. Nhny plda a htkznapi letbl: kutya, asztal, tv, bicikli. Ezek a valdi objektumok kt jellemzvel rendelkeznek: llapottal s viselkedssel. Pldul a kutya llapott a neve, szne, fajtja, hessge stb. jellemzi, viselkedse az ugats, evs, csahols, farok-csvls stb. lehet. A bicikli llapott a sebessgfokozat, a pillanatnyi sebessg, viselkedst a gyorsuls, fkezs, sebessgvlts adhatja. A programbeli objektumok modelljei a valdi objektumoknak. Az objektum llapott egy vagy tbb vltozval, a viselkedst az objektumhoz rendelt metdussal (fggvnynyel) rjuk le. Definci: Az objektum vltozkbl s kapcsold metdusokbl felptett egysg. A vals let objektumait lerhatjuk program objektumokkal. Ha szksg van arra, hogy valdi kutykat brzoljunk egy animcis programban, akkor hasznlhatunk program objektumokat az elvont fogalmak modellezsre. Pldul egy htkznapi esemnyt modellezhet egy billentylets vagy egrkattints. Egy biciklit modellez objektum vltozkkal rja le a pillanatnyi llapotot: a sebessg 18 km/h, s a sebessgfokozat 5-s. Ezeket a vltozkat pldnyvltozknak nevezzk, mert ezek egy konkrt bicikli llapott rjk le. Az objektumorientlt terminolgiban egy nll objektumot pldnynak is neveznk. A kvetkez bra bemutat egy biciklit modellez objektumot az UML objektumdiagramja (Object diagram) segtsgvel.
http://www.uml.org/
18. oldal
2.2. Az zenet
Amg csak egy objektumunk van, addig nem sok haszna van a programnak. ltalban egy objektum csak egy kis rszt jelenti egy nagyobb alkalmazsnak. Ezrt klcsnhats van az objektumok kztt. A biciklink egy sszetett szerkezet, magban mgis hasznlhatatlan, kapcsolatba kell kerlnie ms objektummal, pl. velnk a pedlon keresztl. A program objektumok hatnak egymsra s kommuniklnak egymssal zeneteken keresztl. Amikor az A objektum meghvja a B objektum egy metdust, tulajdonkppen egy zenetet kld neki. Ezt az UML szekvencia diagramja a kvetkez mdon brzolja (az id fentrl lefel halad):
2.Objektumorientlt paradigma
A: B:
19. oldal
zenet
Nha a fogad objektum tbb informcit ignyel, hogy pontosan tudja, mi a dolga. Pldul amikor sebessget vltunk a biciklin, megadjuk a kvnt sebessgvlts irnyt is. Ezt az informcit paramterknt adjuk az zenethez. Az zenet hrom rsze sszefoglalva: Melyik objektum az zenet cmzettje A vgrehajtand metdus neve Az esetleges paramterek
Ez a hrom sszetev elegend, hogy a meghvott objektum vgrehajtsa a kvnt metdust. Az zenetek kt fontos elnnyel jrnak: Egy objektum viselkedst meghatrozzk a metdusai, zenetkldssel megvalsthat az sszes lehetsges kapcsolat kt objektum kztt. Nem szksges, hogy az objektumok ugyanabban a folyamatban, vagy akr ugyanazon gpen legyenek, az zenetklds s fogads ettl fggetlenl lehetsges.
zenetek a gyakorlatban
Az elmleti objektumorientlt szemlletben megklnbztetnk aszinkron s szinkron zenetkldses rendszert. Br a htkznapi modellt az aszinkron megkzelts jellemzi, gyakorlati, megvalsthatsgi okokbl a programnyelvek tbbnyire a szinkron zenetkldses modellen alapulnak.
2.3. Az osztly
A valdi vilgban gyakran sok objektummal tallkozunk ugyanabbl a fajtbl. Pldul a biciklink nagyon sok ms biciklire jelentsen hasonlt. Az objektumorientlt szhasznlatban azt mondjuk, hogy egy konkrt bicikli a biciklik osztlynak egy pldnya. A biciklik rendelkeznek llapottal (aktulis sebessgfokozat, fordulatszm stb.) s viselkedssel (sebessgvlts, fkezs). Ennek ellenre minden bicikli konkrt llapota fggetlen az sszes tbbi bicikli llapottl. Definci: Osztlyozsnak nevezzk azt a folyamatot, amelynek sorn a hasonl objektumokat kzs csoportokba, ms nven osztlyokba soroljuk. Amikor a biciklik kszlnek, a gyrtk nyeresget szeretnnek ellltani, ezrt a biciklik nagy mennyisgben, kzs tervrajz alapjn sorozatgyrtsban kszlnek. Nagyon rossz lenne a hatsfok, ha minden biciklihez egyedi tervrajzot kellene kszteni.
20. oldal
Az objektumorientlt programokban is hasonl a helyzet: kzs tervezsre ad lehetsget, hogy sok objektum hasonl jellemzkkel rendelkezik: tglalapok, alkalmazottak, videofelvtelek, stb. A kerkprgyrtkhoz hasonlan neknk is elnys az, ha sok hasonl objektumot kzs tervrajz alapjn kszthetnk el. Az objektumok tervrajzait hvjuk osztlyoknak. Definci: Az osztly bizonyos fajta objektumok kzs vltozit s metdusait ler tervrajz. A bicikli osztly legszksgesebb pldnyvltozi az aktulis sebessg s a sebessgfokozat lehetnek. Az osztly tartalmazza a pldnymetdusokat is: a sebessgvltst s a fkezst, ahogy a kvetkez UML osztlydiagramon (Class diagram) ltszik:
Miutn ltrehoztuk a Bicikli osztlyt, az osztly alapjn akrmennyi bicikli objektumot ltre tudunk hozni. Amikor pldnyostunk egy osztlybl, a futtatrendszer elegend memrit foglal az objektum pldnyvltozinak. Minden pldny kap egy msolatot a definilt vltozkrl:
2.Objektumorientlt paradigma
21. oldal
class BicycleDemo { public static void main(String[] args) { // Create two different Bicycle objects Bicycle bike1 = new Bicycle(); Bicycle bike2 = new Bicycle(); // Invoke methods on those objects bike1.changeCadence(50); bike1.speedUp(10); bike1.changeGear(2); bike1.printStates(); bike2.changeCadence(50); bike2.speedUp(10); bike2.changeGear(2); bike2.changeCadence(40); bike2.speedUp(10); bike2.changeGear(3); bike2.printStates(); } }
A pldnyvltozk mellett az osztlyok definilhatnak osztlyvltozkat is. Az osztlyvltozk az sszes objektumpldny szmra megosztott informcikat tartalmaznak. Pldul kpzeljk el, hogy az sszes kerkpr ugyanannyi sebessgfokozattal rendelkezik. Ebben az esetben felesleges pldnyvltozt alkalmazni, minden pldny ugyanazt a msolatot troln. Ilyenkor osztlyvltozban rdemes az adatot trolni, amit minden pldny el tud rni. Ha egy objektum megvltoztatja az rtkt, az sszes objektum szmra is megvltozik. Az osztlynak lehet osztlymetdusa is. Az objektumok hasznlatnak elnye a modularits s az informcielrejts. Az osztlyok hasznlatnak elnye az jrafelhasznlhatsg. A bicikligyrak jra s jra fel tudjk hasznlni a gyrts sorn az egyszer elksztett tervrajzokat. A programozk ugyanazokat az osztlyokat, ugyanazokat a kdokat jra s jra felhasznljk a pldnyosts sorn.
2.4. Az rklds
Az objektumorientlt rendszerekben egyes objektumok kztt tovbbi sszefggseket figyelhetnk meg. Bizonyos feltteleknek megfelel objektumok egy msik osztlyba sorolhatk. Pldul a hegyi vagy ppen a vrosi biciklik a biciklik specilis fajti. Az objektumorientlt szhasznlatban ezeket leszrmazott osztlynak (leszrmazott osztlynak) nevezzk. Hasonlan, a bicikli osztly sosztlya (szl osztlya, bzisosztlya) a vrosi biciklik osztlynak. Ezt az sszefggst mutatja a kvetkez bra:
22. oldal
Bicikli
Hegyi bicikli
Vrosi bicikli
Iker bicikli
Az objektumorientlt tervezs folyamn hasznlt ltalnosts s specializls fogalmak az osztlyhierarchia kialaktsa sorn hasznlatosak. Az stl a gyermek fel specilisabb osztlyokat ltunk, visszafele pedig egyre ltalnosabbakat. Minden gyermekosztly rkli az sosztly llapott s a metdusait, de nincs ezekre korltozva. A gyermekosztlyok hozzadhatnak vltozkat s metdusokat ahhoz, amit az sosztlytl rklt. A gyermekosztlyok fell tudjk rni az rklt metdusokat, vagy specilisabb megvalstst tud adni azoknak. Pldul a Hegyi bicikli a Bicikli leszrmazottja:
class MountainBike extends Bicycle { // j adattagok s metdusok helye }
Az rkldsnl nem vagyunk behatrolva egy szintre. Az rklsi fa, vagy ms nven az osztlyhierarchia tbb szint rklst is lehetv tesz, br egy tlagos felhasznli program esetn legtbbszr 4-5 szint elegend. Az rklds a kvetkez elnykkel jr: A leszrmazott osztlyok tudjk specializlni az sosztlytl rklt viselkedst. Az rklds segtsgvel az egyes osztlyokat jra fel lehet hasznlni. A programozk meg tudnak valstani olyan viselkedseket, amelyek az sosztlyban mg nem voltak konkrtan lerva. (Az ilyen osztlyokat absztrakt, elvont osztlyoknak nevezzk.) Az absztrakt sosztlyok csak rszben valstjk meg a szksges viselkedseket, s akr ms programozk fogjk azt a leszrmazottakban megvalstani.
Megjegyzs: Az objektumorientlt szemllet megismerse utn sok fejleszt szmra ers a ksrts, hogy olyankor is az rkldst alkalmazza, amikor inkbb ms technikkat (pl. kompozci, aggregci) rdemes alkalmazni.
Javban az Object osztly az osztlyhierarchia legfels eleme, minden ms osztly belle szrmazik (kzvetlenl vagy kzvetve). Az Object tpus vltoz brmilyen objektumra tud hivatkozni. Az Object osztlynak olyan megosztott viselkedsei (metdusai) vannak, amelyek lehetv teszik a Java VM-en val futst. Pldul minden osztly rkli a toString metdust, hogy az objektum sztringknt is megmutathat legyen.
2.Objektumorientlt paradigma
23. oldal
Java interfsz
rdemes itt megemlteni, hogy ez az elmleti fogalom nem egyezik meg a Java interfsz fogalmval. A Java nyelven bell az interfsz egy tpus, mint ahogy az osztly is tpus. Az osztlyhoz hasonlan az interfsz is definil metdusokat, de attl eltren soha nem valst meg metdust. Az interfszt megvalst osztly fogja annak metdusait megvalstani. Az interfszek hasznosak a kvetkez esetekben: Hasonlsgok megfogalmazsa anlkl, hogy mesterklt osztlyhierarchit ptennk fel Olyan metdusok definilsa, amelyeket tbb osztlyban meg kell valstani Tbbszrs rklds modellezse a ms nyelvekbl ismert veszlyek nlkl
24. oldal
Az objektum pldnyokat tulajdonsgaik s viselkedsk alapjn osztlyokba soroljuk. Csak akkor kldhet zenet egy objektumnak, ha a kld s a fogad objektum kapcsolatban llnak egymssal. Ha kt objektum llapota megegyezik, akkor a kt objektum azonos. Az osztly meghatrozza objektumainak viselkedst. Ha kt objektum ugyanahhoz az osztlyhoz tartozik, s ugyanaz az llapota, akkor ugyanarra az zenetre ugyangy reagl.
3.Vltozk
25. oldal
3. Vltozk
A BasicsDemo program sszeadja 1-tl 10-ig az egsz szmokat, majd kirja az eredmnyt.
public class BasicsDemo { public static void main(String[] args) { int sum = 0; for (int current = 1; current <= 10; current++) { sum += current; } System.out.println("Sum = " + sum); } }
Ez a kis program hasznlja az alapvet nyelvi elemeket: vltozkat, opertorokat s vezrlsi szerkezeteket. Az objektum az llapott vltozkban trolja. Definci: A vltoz olyan adatelem, amely azonostval van elltva. Egy vltoz nevt s tpust egyrtelmen meg kell adni a programunkban, ha hasznlni akarjuk azt. A vltoz neve csak rvnyes azonost lehet: tetszleges hosszsg Unicode karakterekbl ll sorozat, de az els helyen csak bet szerepelhet. A vltoz tpusa meghatrozza, hogy milyen rtkeket vehet fel a vltoz, s milyen mveleteket hajthatunk vgre rajta. A vltoz nevt s tpust a vltozdeklarciban adjuk meg, ami ltalban ehhez hasonl:
type name;
A vltoz rendelkezik hatkrrel (rvnyessgi tartomnnyal) is. A hatskrt a vltozdeklarci helye egyrtelmen meghatrozza. Az albbi plda klnbz vltozk deklarcijt mutatja:
public class MaxVariablesDemo { public static void main(String args[]) { byte largestByte = short largestShort int largestInteger long largestLong = Byte.MAX_VALUE; = Short.MAX_VALUE; = Integer.MAX_VALUE; Long.MAX_VALUE;
float largestFloat = Float.MAX_VALUE; double largestDouble = Double.MAX_VALUE; char aChar = 'S'; boolean aBoolean = true;
26. oldal
A program kimenete:
largest byte value is 127 largest short value is 32767 largest integer value is 2147483647 largest long value is 9223372036854775807 largest float value is 3.40282e+38 largest double value is 1.79769e+308 character S is upper case. value of aBoolean is true
3.1. Adattpusok
Minden vltoz rendelkezik adattpussal. A vltoz adattpusa hatrozza meg, hogy milyen rtkeket vehet fel a vltoz, s milyen mveletek vgezhetk vele. A MaxVariablesDemo pldaprogramban az
int largestInteger;
deklarl egy largestInteger nev vltozt int adattpussal. Az int tpus csak egsz szmot tud trolni. A Java nyelvben az adattpusoknak kt tpusa van: primitv s referencia tpusok. A primitv adattpusok egy egyszer rtket kpesek trolni: szmot, karaktert vagy logikai rtket. A vltoz neve (variableName) kzvetlenl egy rtket (value) jelent.
A kvetkez tblzat az sszes primitv tpust tartalmazza. A pldaprogramunk minden tpusbl deklarl egyet.
3.Vltozk Tpus (egszek) byte short int long bjt mret egsz rvid egsz egsz hossz egsz Lers Mret/formtum
27. oldal
8-bit kettes komplemens 16-bit kettes komplemens 32-bit kettes komplemens 64-bit kettes komplemens
(vals szmok) float double egyszeres pontossg lebegpontos dupla pontossg lebegpontos 32-bit IEEE 754 64-bit IEEE 754
(egyb tpusok) char boolean karakter logikai rtk 16-bit Unicode karakter true vagy false
A tmbk, az osztlyok s az interfszek referencia-tpusak. A referencia-vltoz ms nyelvek mutat vagy memriacm fogalmra hasonlt. Az objektum neve (objectName) nem egy kzvetlen rtket, hanem csak egy referencit (reference) jelent. Az rtket kzvetetten, a referencin keresztl rhetjk el:
Konvenci (teht nem ktelez, de szoks), hogy a vltozneveket kisbetvel kezdjk, az osztlyneveket pedig naggyal. Ha a nv tbb szbl ll ssze, a kzbls szavak kezdbetit mindig naggyal rjuk. A tbbszavas nevek ragasztsra ms nyelvekben hasznlt _ karakter Javban nem hasznlatos.
28. oldal
A tagvltoz (member variable) az osztly vagy objektum rsze. Az osztlyon bell, de a metdusokon kvl lehet deklarlni. A tagvltoz az osztly egszben lthat. A loklis vltozk (local variable) egy kdblokkon bell vannak. A lthatsguk a deklarci helytl az ket kzvetlenl krlvev blokk vgig tart. A metdusok formlis paramterei (method parameters) az egsz metduson bell lthatk. A kivtelkezel paramterek (exception handler parameters) hasonlk a formlis paramterekhez. Figyeljk meg a kvetkez pldt:
if (...) { int i = 17; ... } System.out.println("The value of i = " + i); //error
Az utols sor kvl van az i loklis vltoz rvnyessgi krn, ezrt a fordts hibval lell.
3.Vltozk
byte largestByte = short largestShort int largestInteger long largestLong = Byte.MAX_VALUE; = Short.MAX_VALUE; = Integer.MAX_VALUE; Long.MAX_VALUE;
29. oldal
float largestFloat = Float.MAX_VALUE; double largestDouble = Double.MAX_VALUE; char aChar = 'S'; boolean aBoolean = true;
A Java fordt nem engedi meg, hogy inicializlatlan loklis vltozt hasznljunk, vagyis az els hasznlat eltt mindenkppen inicializlni kell azt. Tagvltozk esetn a 0 rtk alaprtelmezett, teht az inicializls elmaradsa esetn az rtk (tpustl fgg) 0 vagy null lesz. Ennek ellenre j szoks tagvltozk 0 kezdrtkt is explicit megadni. A metdusok s konstruktorok formlis paramtereinek, valamint a kivtelkezel paramtereknek nem lehet kezdrtket adni, az rtkt a hvskor kapjk meg.
Megjegyzs: A C++ nyelvvel szemben teht a paramterek esetn nem adhat meg konstans kezdrtk. A kvetkez kd csak C++-ban mkdik, Javban nem:
Vltozk inicializlshoz a legclszerbb ugyanolyan tpus literlt megadni, mint a vltoz. Itt is igaz az az alapelv, hogy az adatvesztssel jr implicit konverzi nem megengedett, teht a kvetkez kd hibs:
int i = 3.2;
Megjegyzs: Az elz pldban szerepl 3.2 literl double tpus, teht pl. float vltoz esetn sem lenne helyes az inicializls. 3.2f lenne az alkalmas float literlt.
A vgleges loklis vltozt nem ktelez a deklarcinl inicializlni, de addig nem hasznlhatjuk a vltozt, amg nem trtnik meg az inicializls:
final int blankFinal; . . . // nem hasznlhat blankFinal = 0;
30. oldal
Lefordul, majd lefut kimenet nlkl Kirja a The age is 1 szveget Lefordul, majd elindul, s futsi hibval lell Nem fordul le
Melyik a helyes forma, ha egy a bett tartalmaz karakterliterlt szeretnnk ltrehozni? a a new Character(a) \000a
Milyen rtkeket vehet fel egy byte tpus vltoz? 0 65 535 (128) 127 (32 768) 32 767 (256) 255
Melyik nem fordul le? int i = 32; float f = 45.0; double d = 45.0;
Melyik sor fordul le hiba s figyelmeztets nlkl? (Minden helyes vlaszt jelljn meg!) float f=1.3; char c="a"; byte b=257; boolean b=null; int i=10;
3.Vltozk Melyik korrekt vltoznv? (Minden helyes vlaszt jelljn meg!) 2variable variable2 _whatavariable _3_ #myvar
31. oldal
Kirja: 0, 1, 1 Kirja: 0, 0, 1 Fordtsi hiba az A jel sorban Fordtsi hiba a B jel sorban Fordtsi hiba mindkt (A s B) sorban
32. oldal
4. Opertorok
Az opertorok egy, kett vagy hrom operanduson hajtanak vgre egy mveletet. Az egyoperandus opertorokat unris opertoroknak hvjuk. Pldul a ++ opertor az operandust 1-el nveli. A ktoperandus opertorokat binris opertoroknak hvjuk. Pldul az = opertor a jobb oldali operandus rtkt a baloldali operandusba msolja. Vgl a hromoperandus opertor hrom operandust vr. Javban egy hromoperandus opertor van, a ?: feltteles opertor. Az unris opertorok lehetv teszik a prefix s postfix jells is:
operator op op operator //prefix //postfix
Az sszes binris opertor infix jellst alkalmaz, vagyis az opertor az operandusok kztt szerepel:
op1 operator op2 //infix
A hromoperandus opertor szintn infix jellst tesz lehetv. Az opertor mindkt komponense az operandusok kztt szerepel:
op1 ? op2 : op3 //infix
A mvelet vgrehajtsa utn a kifejezs rtke rendelkezsre ll. Az rtk fgg az opertortl s az operandusok tpustl is. Aritmetikai opertorok esetn a tpus al van rendelve az operandusoknak: ha kt int rtket adunk ssze, az rtk is int lesz. Megjegyzend, hogy a Javban a kifejezsek kirtkelsi sorrendje rgztett, vagyis egy mvelet operandusai mindig balrl jobbra rtkeldnek ki (ha egyltaln kirtkeldnek, lsd rvidzr kirtkels), mg a mvelet elvgzse eltt.
opertor hasznlat Lers + * / % op1 + op2 op1 - op2 op1 * op2 op1 / op2 op1 % op2 op1 s op2 sszeadsa, valamint sztring sszefzs op2 s op1 klnbsge op1 s op2 szorzata op1 s op2 (egsz) hnyadosa op1 s op2 egsz oszts maradka
Az ArithmeticDemo pldaprogram definil kt egsz s kt dupla-pontossg lebegpontos szmot, s t aritmetikai opertort mutat be. Ezen kvl hasznlja a + opertort sztringek sszefzsre. Az aritmetikai opertorok flkvrek:
4.Opertorok
public class ArithmeticDemo { public static void main(String[] args) { int i = 37; int j = 42; double x = 27.475; double y = 7.22; System.out.println("Variable values..."); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" x = " + x); System.out.println(" y = " + y); System.out.println("Adding..."); System.out.println(" i + j = " + (i + j)); System.out.println(" x + y = " + (x + y)); System.out.println("Subtracting..."); System.out.println(" i - j = " + (i - j)); System.out.println(" x - y = " + (x y)); System.out.println("Multiplying..."); System.out.println(" i * j = " + (i * j)); System.out.println(" x * y = " + (x * y)); System.out.println("Dividing..."); System.out.println(" i / j = " + (i / j)); System.out.println(" x / y = " + (x / y)); System.out.println("Computing the remainder..."); System.out.println(" i % j = " + (i % j)); System.out.println(" x % y = " + (x % y)); System.out.println("Mixing types..."); System.out.println(" j + y = " + (j + y)); System.out.println(" i * x = " + (i * x));
33. oldal
} }
A program kimenete:
Variable values... i = 37 j = 42 x = 27.475 y = 7.22 Adding... i + j = 79 x + y = 34.695 Subtracting... i - j = -5 x - y = 20.255 Multiplying... i * j = 1554 x * y = 198.37 Dividing... i / j = 0 x / y = 3.8054
34. oldal
Computing the remainder... i % j = 37 x % y = 5.815 Mixing types... j + y = 49.22 i * x = 1016.58
4.1.1
Implicit konverzi
Amikor egy aritmetikai opertor egyik operandusa egsz, a msik pedig lebegpontos, akkor az eredmny is lebegpontos lesz. Az egsz rtk implicit mdon lebegpontos szmm konvertldik, mieltt a mvelet vgrehajtdna. A kvetkez tblzat sszefoglalja az aritmetikai opertorok rtkt az adattpusok fggvnyben. A szksges konverzik mg a mvelet vgrehajtsa eltt vgre fognak hajtdni. long int double float az egyik operandus sem lebegpontos, s legalbb az egyik long az egyik operandus sem lebegpontos, s nem long legalbb az egyik operandus double legalbb az egyik operandus float, s a msik nem double
A + s - opertorok unris (egyoperandus) opertorokknt is hasznlhatk: +op -op int rtkk konvertlja a byte, short s char rtket aritmetikai negls
A ++ opertor nveli az operandus rtkt, a -- pedig cskkenti eggyel. Mindkettt rhatjuk az operandus el (prefix) s utn (postfix) is. A prefix forma esetn elszr trtnik az rtk nvelse vagy cskkentse, majd a kifejezs rtke is a megvltozott rtk lesz. A postfix hasznlat esetn fordtva trtnik a vgrehajts: elszr rtkeldik ki az operandus, majd utna hajtdik vgre a ++ vagy -- mvelet. A kvetkez SortDemo program mindkt opertort hasznlja:
public class SortDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int i = arrayOfInts.length; --i >= 0; ) { for (int j = 0; j < i; j++) { if (arrayOfInts[j] > arrayOfInts[j+1]) { int temp = arrayOfInts[j]; arrayOfInts[j] = arrayOfInts[j+1]; arrayOfInts[j+1] = temp; } } }
4.Opertorok
for (int i = 0; i < arrayOfInts.length; i++) { System.out.print(arrayOfInts[i] + " "); } System.out.println(); } }
35. oldal
A kvetkez pldban (RelationalDemo) definilunk hrom int tpus szmot, s relcis opertorok hasznlatval sszehasonltjuk ket. Az sszehasonlt mveleteket flkvr bettpussal emeltk ki:
public class RelationalDemo { public static void main(String[] args) { int i = 37; int j = 42; int k = 42; System.out.println("Variable values..."); System.out.println(" i = " + i); System.out.println(" j = " + j); System.out.println(" k = " + k); System.out.println("Greater System.out.println(" i > System.out.println(" j > System.out.println(" k > than..."); j = " + (i > j));//false i = " + (j > i));//true j = " + (k > j));//false; or equal to..."); " + (i >= j));//false " + (j >= i));//true " + (k >= j));//true
36. oldal
System.out.println("Equal to..."); System.out.println(" i == j = " + (i == j));//false System.out.println(" k == j = " + (k == j));//true System.out.println("Not equal to..."); System.out.println(" i != j = " + (i != j));//true System.out.println(" k != j = " + (k != j));//false
} }
Less than... i < j = true j < i = false k < j = false Less than or i <= j = j <= i = k <= j = equal to... true false true
4.Opertorok Opertor && || ! & Alkalmazs op1 && op2 op1 || op2 !op op1 & op2 Lers
37. oldal
Logikai s: true-t ad vissza, ha op1 s op2 egyarnt true; op2 feltteles kirtkels Logikai vagy: true-t ad vissza, ha op1 vagy op2 true; op2 feltteles kirtkels Logikai nem: true-t ad vissza, ha op false Bitenknti s: true-t ad vissza, ha op1 s op2 egyarnt boolean s true; op1 s op2 mindig kirtkeldik; ha mindkt operandus szm, akkor bitenknti s mvelet Bitenknti vagy: true-t ad vissza, ha op1 s op2 egyarnt boolean vagy op1 vagy op2 true; op1 s op2 mindig kirtkeldik; ha mindkt operandus szm, akkor bitenknti vagy mvelet Bitenknti nem: true-t ad vissza, ha op1 s op2 klnbz vagy egyik, vagy msik, de nem egyszerre mindkt operandus true
op1 | op2
op1 ^ op2
4.3.1
Rvidzr kirtkels
Bizonyos esetekben a logikai opertor msodik operandusa nem rtkeldik ki. Pldul a kvetkez esetben:
(numChars < LIMIT) && (...)
Az && opertor csak akkor ad vissza true-t, ha mindkt operandus true. Teht, ha numChars nagyobb vagy egyenl, mint LIMIT, akkor && bal oldala false, s a kifejezs viszszaadott eredmnye a jobb oldali operandus kirtkelse nlkl szletik meg. Ilyen esetekben a fordt nem rtkeli ki a jobb oldali operandust. Ilyenkor a jobb oldali kifejezs miatt kzvetett mellkhatsok lphetnek fel, pldul ha adatfolyambl olvasunk, rtkeket aktualizlunk, vagy szmtsokat vgznk a jobb oldali operandusban. Ehhez hasonlan, ha a || opertor bal oldali operandusa igaz, felesleges a jobboldalt kirtkelni, nem is fog megtrtnni. Ha mindkt operandus logikai, az & opertor hasonlan viselkedik, mint az &&. Azonban & mindig kirtkeldik s true-t ad vissza, ha mindkt operandusa true. Ha az operandusok boolean-tpusak, | azonos mveletet vgez, mint ||. A fenti mkds miatt nem rdemes olyan kdot kszteni, amelyik a jobboldali operandusnak kirtkelse sorn a kirtkelsen tl mst is tesz. Pldul veszlyes, nehezen ttekinthet lesz a kvetkez feltteles kifejezs:
if (a < b && b++ < f(c) ) {...}
Ha a bal oldali operandus (a<b) hamis, akkor sem a ++ opertor, sem az f fggvnyhvs nem fog vgrehajtdni.
38. oldal
Mindegyik opertor az els operandus bitjeit lpteti az opertor ltal megadott irnyba a msodik operandus rtkvel. Pldul a kvetkez kifejezsben a 13-as egsz szm bitjeit lptetjk 1-el jobbra:
13 >> 1;
A 13-as szm kettes szmrendszerbeli rtke: 1101. A lptets eredmnye: 1101 egy pozcival jobbra - 110, (decimlisan 6). A bal oldali biteket 0-val tltttk fel. A kvetkez tblzatban a Java programozsi nyelvben hasznlatos bitenknti logikai opertorokat s funkcijukat lthatjuk: Opertor & | ^ ~ Alkalmazs op1 & op2 op1 | op2 op1 ^ op2 ~op2 Lers Bitenknti s, ha mindkt operandus szm; feltteles s ha mindkt operandus logikai Bitenknti vagy, ha mindkt operandus szm; feltteles vagy, ha mindkt operandus logikai Bitenknti kizr vagy (xor) Bitenknti negci
s
Ha az operandus szm, az & opertor bitenknti s mveletet hajt vgre pronknt (helyrtk szerint) az operandus bitjein. Az s mvelet akkor ad vissza 1-et, ha a kifejezs mindkt bitje 1. Ha az s mveletet kt decimlis szmon hajtjuk vgre, pldul a 12-n s 13-n (12&13) akkor az adott szmok kettes szmrendszerbeli alakjn bitenknt kell vgrehajtanunk az s mveletet. Az eredmny gy 12-lesz decimlisan. Ha mindkt operandus 1, az s mvelet eredmnyknt is 1-et ad. Ellenkez esetben 0-t.
4.Opertorok
39. oldal
Vagy
Ha mindkt operandus szm, akkor a | opertor a vagy mveletet hajtja vgre. A vagy mvelet 1-et ad eredmnyl, ha kt bit kzl brmelyik rtke 1.
Kizr vagy
Ha mindkt operandus szm, akkor a ^ opertor a kizr vagy (xor) mveletet hajtja vgre. Kizr vagy esetn a kifejezs eredmnye akkor egy, ha a kt operandus bit klnbz, ellenkez esetben az eredmny 0.
Negci
Vgl a negcis opertor (~) az operandus bitjeit egyenknt az ellenkezjre fordtja: ha az operandus bitje 1, akkor az eredmny 0, ha az operandus bitje 0, akkor az eredmny 1. Pldul: ~1011 (11) = 0100 (4).
4.4.1
Bitmanipulcik a gyakorlatban
Egyebek kztt a bitenknti mveletekkel hasznosan kezelhetk a logikai bitek is. Tegyk fel pldul, hogy az adott programban vannak logikai bitek, melyek a klnbz sszetevk llapott hatrozzk meg a programban. Ez clravezetbb, mint klnbz boolean vltozk definilsa. Bitmanipulci segtsgvel bellthatk, s vltoztathatk az adott bitek rtkei. Elszr definiljunk konstansokat, melyek a program klnbz bitjeit hatrozzk majd meg. Ezek a konstansok a kettes szmrendszer klnbz helyi rtkei, gy biztosthatjuk, hogy ksbb nem lesznek sszekeverhetk. Ksbb ezek a konstansok a bit vltozk rtkeit segtik majd kinyerni. A kvetkez pldban a biteket 0 rtknek inicializljuk, ami azt jelenti, hogy minden rtk hamis.
static static static static final final final final int int int int VISIBLE = 1; DRAGGABLE = 2; SELECTABLE = 4; EDITABLE = 8;
int flags = 0;
A VISIBLE szimbolikus konstans jelzi, ha valami lthatv vlik a programban. Ezt a bitet lltja egyesre a kvetkez sor:
flags = flags | VISIBLE;
Itt lthat a teljes program (BitwiseDemo), mely magban foglalja a fenti kdot:
public class BitwiseDemo { static static static static final final final final int int int int VISIBLE = 1; DRAGGABLE = 2; SELECTABLE = 4; EDITABLE = 8;
40. oldal
float largestFloat = Float.MAX_VALUE; double largestDouble = Double.MAX_VALUE; char aChar = 'S'; boolean aBoolean = true;
A Java programozsi nyelv azt is megengedi a rvidtett rtkad opertorok segtsgvel, hogy aritmetikai, rtknvelsi, valamint bitenknti mveletvgzst sszekssk az rtkadssal. Pldul, ha egy vltoz rtkt akarjuk nvelni, akkor:
i=i+2;
A fenti kt rtkads megegyezik. A kvetkez tblzat tartalmazza a rvidtett rtkad opertorokat s a hosszabb alakjukat. Opertor Hasznlat += op1 += op2 Egyezik op1 = op1 + op2
4.Opertorok -= *= /= %= &= |= ^= <<= >>= >>>= op1 -= op2 op1 *= op2 op1 /= op2 op1 %= op2 op1 &= op2 op1 |= op2 op1 ^= op2 op1 <<= op2 op1 >>= op2 op1 >>>= op2 op1 = op1 - op2 op1 = op1 * op2 op1 = op1 / op2 op1 = op1 % op2 op1 = op1 & op2 op1 = op1 | op2 op1 = op1 ^ op2 op1 = op1 << op2 op1 = op1 >> op2 op1 = op1 >>> op2
41. oldal
6 0 1 7
43. oldal
5.1. Kifejezsek
A kifejezsek hajtjk vgre a program feladatt. A kifejezseket tbbek kztt vltozk kiszmtsra, rtkk belltsra s a program futsnak ellenrzsre hasznljuk. A kifejezseknek ktfle feladata van: vgrehajtani a szmtsokat, amelyeket a kifejezs alkotelemi hatroznak meg, s visszaadni a szmts vgeredmnyt. Definci: A kifejezs vltozk, opertorok s metdushvsok olyan sorozata (a nyelv szintaxist figyelembe vve) amely egy rtket ad vissza. Ahogy az elzekben mr emltettk, az opertorok egy rtket adnak vissza, gy az opertor hasznlatval egy kifejezst kapunk. A MaxVariablesDemo program rszlete nhnyat bemutat a program kifejezsei kzl:
... char aChar = 'S'; boolean aBoolean = true; System.out.println("The largest byte value is " + largestByte); ... if (Character.isUpperCase(aChar)) { ... }
A kifejezsek kirtkelse sorn vgrehajtsra kerlnek mveletek, s a kifejezs visszaad egy rtket, mint az a kvetkez tblzatban is lthat: Kifejezs aChar = 'S' Mvelet Az 'S' karaktert adja rtkl az aChar karakter tpus vltoznak sszefzi a sztringet s a largestByte rtkt sztringg konvertlva isUpperCase metdus hvsa Visszaadott rtk aChar rtke az rtkads utn ('S') Az eredmny az szszefztt sztring A metdus visszatrsi rtke: true
A kifejezs ltal visszaadott rtk adattpusa fgg a kifejezsben hasznlt alkotelemektl. Az aChar = 'S' kifejezs egy karaktert ad vissza, mert az rtkad opertor ugyan-
44. oldal
olyan tpus rtkkel tr vissza, mint amilyenek az operandusai, s az aChar valamint az 'S' karakter tpusak. A tbbi kifejezsnl mr lthattuk, hogy egy kifejezs egy boolean rtkkel, egy sztringgel s egyb rtkekkel is visszatrhet. A Java nyelv lehetsget biztost sszetett kifejezsek s utastsok ltrehozsra kisebb kifejezsekbl, amg a kifejezs egyik rszben hasznlt adattpusok megegyeznek a tbbi rsz adattpusaival. Itt lthatunk egy pldt sszetett kifejezsre:
x * y * z
Ebben a klnleges pldban a sorrend, amely szerint a kifejezs kirtkeldik, nem fontos, mivel a szorzs eredmnye nem fgg a tagok sorrendjtl, a vgeredmny mindig ugyanaz, nem szmt, milyen sorrendben vgezzk el a szorzsokat. Azonban ez nem minden kifejezsre igaz. Pldul a kvetkez kifejezs klnbz eredmnyt ad attl fggen, hogy az sszeads vagy az osztst megvalst opertor hajtdik-e vgre elsknt:
x + y / 100
Zrjelezssel meghatrozhatjuk, hogy egy kifejezs hogyan rtkeldjn ki. Pldul gy tehetjk egyrtelmv a vgrehajtst az elz plda esetben:
(x + y)/ 100
Ha hatrozattan nem jelezzk a sorrendet, amely szerint akarjuk, hogy az sszetett kifejezs kirtkeldjn, akkor a sorrendet az opertorok precedencija fogja meghatrozni. A magasabb precedencival rendelkez opertorok hajtdnak vgre elsknt. Pldul az oszts opertor magasabb precedencij, mint az sszeads. gy a kvetkez kt kifejezs megegyezik egymssal:
x + y / 100 x + (y / 100)
Ha sszetett kifejezst runk, akkor kifejezetten figyelnnk kell a zrjelezsre s arra, hogy mely opertoroknak kell kirtkeldnik elsknt. Ennek a gyakorlsa segthet a forrskd jobb olvashatsgnak s karbantarthatsgnak elrsben. A kvetkez tblzat a Java platformban hasznlt opertorok precedencia-szintjeit mutatja be. Az opertorok a tblzatban precedencia-szint szerint vannak rendezve: legfell a legnagyobb precedencival rendelkez tallhat. A magasabb precedencival rendelkez opertorok elbb hajtdnak vgre, mint az alacsonyabbal rendelkezk. Az azonos szinten elhelyezked opertorok azonos precedencival rendelkeznek. Ha azonos precedencij opertorok szerepelnek egy kifejezsben, akkor szablyozni kell, hogy melyik rtkeldjn ki elsknt. Minden binris opertor, kivve az rtkad opertorokat balrl jobbra hajtdnak vgre. Az rtkad opertorok jobbrl balra hajtdnak vgre.
45. oldal
bitenknti kizr vagy ^ bitenknti vagy logikai s logikai vagy feltteles rtkads | && || ?: = += -= *= /= %= &= ^= |= <<= >>= >>>=
5.2. Utastsok
Az utastsok nagyjbl a beszlt nyelv mondatainak felelnek meg. Az utasts egy konkrt futsi egysget hoz ltre. A kvetkez kifejezstpusok szervezhetk utastsokba, amelyek pontosvesszvel vgzdnek (;): rtkad kifejezsek
++ s -- hasznlata
Az utastsoknak ezt a fajtjt kifejezs utastsoknak nevezzk. Itt lthatunk pr pldt a kifejezs-utastsokra:
aValue = 8933.234; aValue++; System.out.println(aValue); Integer integerObject = new Integer(4); //rtkad utasts //nvels //metdus hvs //objektum ltrehozs
A kifejezs-utastsokon kvl mg ktfle tpust kell megemltennk. A deklarcis utasts ltrehoz egy vltozt. Sok pldt lthattunk mr deklarcis utastsokra.
double aValue = 8933.234; //deklarcis utasts
46. oldal
A vgrehajts-vezrl utasts szablyozza, hogy az utastsok milyen sorrendben hajtdnak vgre. A for ciklus s az if utasts j pldk a vgrehajts-vezrl szerkezetre.
5.3. Blokkok
A blokk nulla vagy tbb utasts kapcsos zrjelek kztt, amely hasznlhat brhol, ahol az nll utastsok megengedettek. A kvetkez rszlet kt blokkot mutat be MaxVariablesDemo programbl, mindegyik tartalmaz egy nll utastst:
if (Character.isUpperCase(aChar)) { System.out.println("The character " + aChar + " is upper case."); } else { System.out.println("The character " + aChar + " is lower case."); }
5.4. sszefoglals
Egy kifejezs vltozk, opertorok s metdushvsok sorozata (a nyelv szintaxist figyelembe vve), amely egy rtket ad vissza. rhatunk sszetett kifejezseket is egyszerbbekbl sszelltva mindaddig, amg a magban foglalt, az opertorokhoz szksges adattpusok megfelelek. Ha sszetett kifejezst runk, akkor kifejezetten figyelnnk kell a zrjelezsre s arra, hogy mely opertoroknak kell kirtkeldnik elsknt. Ha nem hasznljuk a zrjelezst, akkor a Java platform az opertorok precedencija szerint rtkeli ki az sszetett kifejezst. A korbbi tblzat mutatja be a Java platformban megtallhat opertorok precedencijt. Az utasts egy konkrt utastsi egysget valst meg, amelyet pontosvessz zr le (;). Az utastsoknak hrom fajtja van: kifejezs utastsok, deklarcis utastsok, vgrehajts-vezrl utastsok. Nulla vagy tbb utastsbl a kapcsos zrjelek segtsgvel blokkokat alakthatunk ki: { s }. Habr nem szksges, ajnlott az alkalmazsa akkor is, ha a blokk csak egy utastst tartalmaz.
47. oldal
rjon programot, amely kiszmtja s kirja a msodfok egyenlet kt megoldst! (Felttelezzk, hogy kt megolds ltezik, a gyk alatti kifejezs esetleges negatv voltval most nem kell foglalkozni.) x1, 2 = b b 2 4ac 2a
Hozzon ltre a, b s c vals tpus vltozkat tetszleges kezdrtkkel! Hozzon ltre x1 s x2 nev vltozkat, s vgezze el a szmtsokat! (A ngyzetgykvonsra a Math.sqrt() metdust lehet alkalmazni. A metdus negatv paramter esetn NaN specilis rtket adja.) rja ki az eredmnyeket a konzolra! Mdostsa a programot gy, hogy a diszkriminns (a gykjel alatti kifejezs) rtkt egy d nev vltozba szmtsa ki elszr, majd ennek felhasznlsval szmtsa az x1 s x2 rtkt. (Plda adatok a tesztelshez: a = 1, b = -5, c = 6 esetn x1=2, x2=3) rjon programot, amelyik kirajzolja a karcsonyft!
/ \ \ / \ ----------" " " " " " / / \
48. oldal
6. Vezrlsi szerkezetek
6.1. A while s a do-while ciklusok
A while ciklus utastsblokk vgrehajtsra hasznlhat, amg a felttel igaz. A while ciklus szintaxisa:
while (felttel) { utastsok }
A while ciklus elszr kirtkeli a felttelt, amely mvelet egy boolean rtket ad vissza. Ha a kifejezs rtke igaz, a while ciklus vgrehajtja while blokkjban szerepl utastsokat. A while ciklus addig rtkeli ki a kifejezst s hajtja vgre az utastsblokkot, amg a kifejezs hamis rtk nem lesz. A kvetkez WhileDemo nev pldaprogram a while ciklust hasznlja fel, amely megvizsglja a sztring karaktereit, hozzfzi a sztring minden karaktert a sztring puffer vghez, amg g betvel nem tallkozik.
public class WhileDemo { public static void main(String[] args) { String copyFromMe = "Copy this string until you " + "encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); while (c != 'g') { copyToMe.append(c); c = copyFromMe.charAt(++i); } System.out.println(copyToMe);
} }
A Java nyelv egy a while ciklushoz hasonl utastst is biztost a do-while ciklust. A do-while szintaxisa:
do { utasts(ok) } while (felttel);
Ahelyett, hogy a felttelt a ciklus vgrehajtsa eltt rtkeln ki, a do-while ezt a ciklusmag lefutsa utn teszi meg. gy a do-while magjban szerepl utastsok minimum egyszer vgrehajtdnak. Itt lthat az elz program do-while ciklussal megvalstva, ami a DoWhileDemo nevet kapta:
6.Vezrlsi szerkezetek
public class DoWhileDemo { public static void main(String[] args) {
49. oldal
String copyFromMe = "Copy this string until you " + "encounter the letter 'g'."; StringBuffer copyToMe = new StringBuffer(); int i = 0; char c = copyFromMe.charAt(i); do { copyToMe.append(c); c = copyFromMe.charAt(++i); } while (c != 'g'); System.out.println(scopyToMe);
} }
Az inicializls egy olyan kifejezs, amely kezdrtket ad a ciklusnak ez egyszer, a ciklus elejn fut le. A felttel kifejezs azt hatrozza meg, hogy meddig kell a ciklust ismtelni. Amikor a kifejezs hamisknt rtkeldik ki, a ciklus nem folytatdik. Vgezetl a nvekmny egy olyan kifejezs, amely minden ismtlds utn vgrehajtdik a ciklusban. Mindezen sszetevk opcionlisak. Tulajdonkppen ahhoz, hogy egy vgtelen ciklust rjunk, elhagyjuk mindhrom kifejezst:
for ( ; ; ) { ... }
A for ciklusokat gyakran arra hasznljuk, hogy egy tmb elemein vagy egy karakterlncon vgezznk itercit. Az albbi plda, ForDemo, egy for utastst hasznl arra, hogy vgighaladjon egy tmb elemein s kirja ket.
50. oldal
public class ForDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int i = 0; i < arrayOfInts.length; i++) { System.out.print(arrayOfInts[i] + " "); } System.out.println();
} }
Megjegyezzk, hogy egy loklis vltoz is deklarlhat a for ciklus inicializl kifejezsben. Ennek a vltoznak az rvnyessge a deklarcijtl a for utasts ltal vezrelt blokk vgig terjed, teht mind a lezr s a nvekmny kifejezseiben is hasznlhatk. Ha a for ciklust vezrl vltozra nincs szksg a cikluson kvl, a legjobb, ha a vltozt az rtkad kifejezsben deklarljuk. Az i, j s k neveket gyakran a for ciklusok vezrlsre hasznljuk, ezeknek a for ciklus rtkad kifejezsn bell val deklarlsa leszkti lettartamukat, s cskkenti a hibalehetsgeket.
Itt egy kis kdrszlet, ami ugyanazt a feladatot vgzi, mint az elz kdrszlet.
public class ForEachDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int element : arrayOfInts) { System.out.print(element + " "); } System.out.println();
} }
A kibvtett for utasts igazn akkor elnys, amikor gyjtemnyekre alkalmazzuk (osztlyok, amik a Collection interfszt implementljk). Itt lthat egy rgi tpus for utasts, ami itertor segtsgvel egy gyjtemnyen halad vgig:
void cancelAll(Collection<TimerTask> c) { for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); ) i.next().cancel(); }
Most nem kell aggdnunk a klns <TimerTask> kdrszlet miatt. Ksbb fogunk magyarzatot adni a rszletekre. A lnyeg az, hogy elkerlhetjk ezt a kibvtett for ciklus hasznlatval:
6.Vezrlsi szerkezetek
void cancelAll(Collection<TimerTask> c) { for (TimerTask t : c) t.cancel(); }
51. oldal
Amikor itercikat gyazunk egybe, a kibvtett for utasts mg jobb, mivel flsleges kdrszeket kerlhetnk el. Pldul:
for (Suit suit : suits) { for (Rank rank : ranks) sortedDeck.add(new Card(suit, rank)); }
A kibvtett for utasts sajnos nem mkdik mindenhol. Hogyha pl. tmbindexekhez akarunk hozzfrni, a kibvtett for nem fog mkdni. Amikor csak lehet, a tovbbfejlesztett for-t hasznljuk, tbb programhibt is kikszblhetnk, s a forrskdunk rendezettebb lesz.
Ez az if utasts legegyszerbb formja. Az if ltal vezrelt blokk vgrehajtdik, ha a felttel igaz. ltalban az if egyszer alakja gy nz ki:
if (felttel) { kifejezsek }
Mi van akkor, ha az utastsok ms vltozatt akarjuk futtatni, ha a felttel kifejezs hamis? Erre az else utastst hasznlhatjuk. Vegynk egy msik pldt. Tegyk fel azt, hogy a programunknak klnbz mveleteket kell vgrehajtania attl fggen, hogy a felhasznl az OK gombot vagy ms gombot nyom meg a figyelmeztet ablakban. A programunk kpes lehet erre, ha egy if utastst egy else utastssal egytt hasznlunk.
if (response == OK) { //code to perform OK action } else { //code to perform Cancel action }
Az else blokk akkor kerl vgrehajtsra, ha az if felttele hamis. Az else utasts egy msik formja az else if egy msik felttelen alapulva futtat egy utastst. Egy if utastsnak lehet akrhny else if ga, de else csak egy. Az albbi IfElseDemo program egy teszt pontszmot alapul vve egy osztlyzatot hatroz meg: 5-s 90%-rt vagy afltt, 4-es 80%-rt vagy afltt s gy tovbb:
public class IfElseDemo { public static void main(String[] args) {
52. oldal
int testscore = 76; int grade; if (testscore >= 90) grade = 5; } else if (testscore grade = 4; } else if (testscore grade = 3; } else if (testscore grade = 2; } else { grade = 1; } } { >= 80) { >= 70) { >= 60) {
Megfigyelhetjk, hogy a testscore rtke tbb kifejezs felttelnek is eleget tehet az albbi if utastsok kzl: 76 >= 70 s 76 >= 60. Azonban, ahogy a vgrehajt rendszer feldolgoz egy olyan sszetett if utastst, mint ez, amint egy felttel kielgl, lefutnak a megfelel utastsok (grade = 3), s a vezrls kikerl az if utastsbl anlkl, hogy a tovbbi feltteleket kirtkeln. A Java programozsi nyelv tmogat egy hromoperandus opertort, ami egyszer esetekben az if utasts helyett alkalmazhat. Az opertor ltalnos alakja:
logikai kifejezs ? kifejezs-ha-igaz : utasts-ha-hamis
A ?: opertor kirtkelsnek eredmnye az upper karaktersorozat lesz, ha az isUpperCase metdus igaz rtket ad vissza, egybknt pedig a lower karaktersorozat. Az eredmny ssze lesz fzve a megjelenteni kvnt zenet ms rszeivel. Ha megszokjuk ezt a szerkezetet, bizonyos esetekben knnyebben olvashatbb s tmrebb teheti a kdunkat.
Megjegyzs: rdemes megfigyelni, hogy mirt is lehetett itt az if-else szerkezetet kivltani a hromoperandus opertorral: az if s else gon is ugyanazt akartuk tenni egy bizonyos kifejezssel: ki akartuk rni. Ha ez a kzs felhasznls nem ll fenn, akkor maradnunk kell az if-else utastsnl. Megjegyzs: ltalban nem felttlenl szksges, mgis sok alkalommal zrjelezzk az egyes operandusokat, s idmknt az egsz opertor-kifejezst is. (Az elz plda az egsz kifejezst zrjeleni.)
6.Vezrlsi szerkezetek
53. oldal
A switch utasts kirtkeli kifejezst, ez esetben a month rtkt, s lefuttatja a megfelel case utastst. Ezltal a program futsi eredmnye az August lesz. Termszetesen ezt az if utasts felhasznlsval is megoldhatjuk:
int month = 8; if (month == 1) { System.out.println("January"); } else if (month == 2) { System.out.println("February"); } ...
Annak eldntse, hogy az if vagy a switch utastst hasznljuk, programozi stlus krdse. Megbzhatsgi s ms tnyezk figyelembevtelvel eldnthetjk, melyiket hasznljuk. Mg egy if utastst hasznlhatunk arra, hogy egy rtkkszlet vagy egy felttel alapjn hozzunk dntseket, addig a switch utasts egy egsz szm rtke alapjn hoz dntst. Msrszt minden case rtknek egyedinek kell lennie, s a vizsglt rtkek csak konstansok lehetnek. Egy msik rdekessg a switch utastsban a minden case utni break utasts. Minden egyes break utasts megszaktja az pp bezrd switch utastst, s a vezrls szla a switch blokk utni els utastshoz kerl. A break utastsok szksgesek, mivel nlklk a case utastsok rtelmket vesztenk. Vagyis egy explicit break nlkl a vezrls folytatlagosan a rkvetkez case utastsra kerl (tcsorog). Az albbi SwitchDemo2 plda azt illusztrlja, hogyan lehet hasznos, ha a case utastsok egyms utn lefutnak.
54. oldal
public class SwitchDemo2 { public static void main(String[] args) { int month = 2; int year = 2000; int numDays = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: numDays = 31; break; case 4: case 6: case 9: case 11: numDays = 30; break; case 2: if ( ((year % || (year numDays = else numDays = break; default: numDays = 0; break; } }
A program kimenete:
Number of Days = 29
Technikailag az utols break nem szksges, mivel a vezrls amgy is befejezdne, kilpve a switch utastsbl. Azonban javasolt ekkor is a break hasznlata, mivel gy a kd knnyebben mdosthat s kevsb hajlamos a hibra. Ksbb mg ltni fogjuk a ciklusok megszaktsra hasznlt break-et. Vgl a switch utastsban hasznlhatjuk a default utastst, hogy mindazokat az rtkeket is kezelhessk, amelyek nem voltak egy case utastsban sem kezelve.
Megjegyzs: A default utastsnak nem kell felttlenl az utolsnak lenni, br gy a leglogikusabb s gy is szoks ltalban elhelyezni. Ugyangy a case gak sorrendjnek is csak akkor lehet jelentsge, ha van olyan g, amelyiket nem zrtunk le breakkel.
6.4.1
A felsorolt adattpus az 5.0-ban bevezetett jdonsg, amirl ksbb olvashat majd. Ez a rsz csak azt mutatja be, hogyan hasznlhatjuk ket egy switch utastsban. Szerencsre ez pont olyan, mint a switch hasznlata az egsz tpus vltozk esetn.
6.Vezrlsi szerkezetek
55. oldal
Az albbi SwitchEnumDemo kdja majdnem megegyezik azzal a kddal, amit korbban a SwitchDemo2-ben lttunk. Ez az egsz tpusokat felsorolt tpusokkal helyettesti, de egybknt a switch utasts ugyanaz.
public class SwitchEnumDemo { public enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER } public static void main(String[] args) { Month month = Month.FEBRUARY; int year = 2000; int numDays = 0; switch (month) { case JANUARY: case MARCH: case MAY: case JULY: case AUGUST: case OCTOBER: case DECEMBER: numDays = 31; break; case APRIL: case JUNE: case SEPTEMBER: case NOVEMBER: numDays = 30; break; case FEBRUARY: if ( ((year % || (year numDays = else numDays = break; default: numDays=0; break; } }
Ez a plda csak egy kis rszt mutatta be annak, amire a Java nyelvi felsorolsok kpesek. A tovbbiakat ksbb olvashatja el.
56. oldal
pus hibkat le tudja kezelni. A kivtelkezel blokk megksrelheti a hiba kijavtst, vagy ha gy tnik, hogy a hiba visszallthatatlan, akkor szablyosan kilp a programbl. Alapveten hrom utasts jtszik szerepet a kivtelkezelsekben: a try utasts tartalmaz egy utasts blokkot, amiben a kivtel dobsa elkpzelhet a catch utasts tartalmaz egy olyan utastsblokkot, ami le tudja kezelni az azonos tpus kivteleket. Az utastsok akkor hajtdnak vgre, ha kivteltpus tpus kivtel vltdik ki a try blokkban a finally egy olyan utasts blokkot tartalmaz, ami vgrehajtdik akkor is, ha a try blokkban hiba trtnt, s akkor is, ha hiba nlkl futott le a kd.
try { utasts(ok) } catch (kivteltpus kivtelobjektum) { utasts(ok) } finally { utasts(ok) }
A break s a continue utastsokat hasznlhatjuk cmkvel vagy anlkl. A cmke egy azonost, ami az utasts eltt helyezkedik el. A cmkt egy kettspont (:) kveti. A kvetkez programrszletben lthatunk egy pldt a cmke alkalmazsra:
statementName: someJavaStatement;
A break utasts
A break utastsnak kt alakja van: cmke nlkli s cmks. A cmke nlkli break utastst korbban a switch-nl mr hasznltuk. Ahol a cmke nlkli break utastssal fejeztk be a sort, ott befejezi a switch utastst, s tadja a vezrlst a switch utn kvetkez utastsnak. A cmke nlkli break utasts hasznlhat mg a for, while vagy dowhile ciklusokbl val kilpsre is. A BreakDemo pldaprogram tartalmaz egy for ciklust, ami egy bizonyos rtket keres egy tmbn bell:
public class BreakDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; int searchfor = 12; int i = 0; boolean foundIt = false;
6.Vezrlsi szerkezetek
for ( ; i < arrayOfInts.length; i++) { if (arrayOfInts[i] == searchfor) { foundIt = true; break; } } if (foundIt) { System.out.println("Found " + searchfor + " at index " + i + '.'); } else { System.out.println(searchfor + "not in the array"); } } }
57. oldal
A break utasts befejezi a for ciklust, ha megvan az rtk. A vezrls taddik a for lezrsa utn lv utastsnak, ami a print utastst tartalmaz if a program vgn.
A program kimenete:
Found 12 at index 4.
Megjegyzs: A for ciklusbl break-kel val kilpst sokszor hasznljuk egy adott rtk keresse rdekben. rdemes megfigyelni, hogy ekkor a ciklus utn meg kell llaptani (if utasts), hogy mirt is fejezdtt be a ciklus: a tallat miatt, vagy mert a vgre rtnk.
A break utasts cmke nlkli alakjt hasznlhatjuk a legbels switch, for, while vagy do-while befejezsre. A cmkzett alak befejez egy olyan kls utastst, ami a break cmkje ltal van azonostva. Msknt fogalmazva: egyszerre tbb utastsbl is kpes kiugrani. A kvetkez (BreakWithLabelDemo) program hasonl az elzhz, de itt ktdimenzis tmbben keressk az rtket. Kett egymsba gyazott for ciklus vizsglja t a tmbt. Amikor az rtk megvan, egy cmkzett break befejezi a search-knt cmkzett utastst, ami a kls for ciklus:
public class BreakWithLabelDemo { public static void main(String[] args) { int[][] arrayOfInts = { { 32, 87, 3, 589 }, { 12, 1076, 2000, 8 }, { 622, 127, 77, 955 } }; int searchfor = 12; int i = 0; int j = 0; boolean foundIt = false; search: for ( ; i < arrayOfInts.length; i++) { for (j = 0; j < arrayOfInts[i].length; j++) { if (arrayOfInts[i][j] == searchfor) { foundIt = true; break search; } } }
58. oldal
A program kimenete:
Found 12 at 1, 0.
Ez a szintaxis egy kicsit zavar lehet. A break utasts befejezi a cmkzett utastst, s nem a cmknek adja t a vezrlst. A vezrls annak az utastsnak addik t, ami kzvetlen a (befejezett) cmkzett utasts utn van.
A continue utasts
A continue utasts arra hasznlhat, hogy tugorjuk a ciklusmag htralev rszt egy for, while vagy do-while ciklusnak. A cmke nlkli alakja tugrik a legbels ciklusmag vgre s kirtkeli a logikai kifejezs rtkt, ami a ciklust vezrli. A kvetkez ContinueDemo program vgigfut egy StringBuffer-en, megvizsglva az sszes bett. Ha a vizsglt karakter nem p, a continue utasts tugorja a ciklus htralev rszt s vizsglja a kvetkez karaktert. Ha ez egy p, a program megnveli a szmll rtkt s talaktja a p-t nagybetss.
public class ContinueDemo { public static void main(String[] args) { StringBuffer searchMe = new StringBuffer( "peter piper picked a peck of pickled peppers"); int max = searchMe.length(); int numPs = 0; for (int i = 0; i < max; i++) { //interested only in p's if (searchMe.charAt(i) != 'p') continue; //process p's numPs++; searchMe.setCharAt(i, 'P'); } System.out.println("Found " + numPs + " p's in the string."); System.out.println(searchMe);
} }
A continue utasts cmks alakja tugorja a cmkzett ciklus ciklusmagjnak htralev rszt. A kvetkez ContinueWithLabelDemo pldaprogram egymsba gyazott ciklusokat hasznl egy szvegrsz keressre egy msik szvegben. Kt egymsba gyazott ciklus szksges: egy, hogy ismtelje a szvegrszt, s egy, hogy addig ismtelje, amg t
6.Vezrlsi szerkezetek
59. oldal
nem vizsglta a szveget. Ez a program a continue cmkzett alakjt hasznlja, hogy tugorjon egy ismtlst a kls ciklusban:
public class ContinueWithLabelDemo { public static void main(String[] args) { String searchMe = "Look for a substring in me"; String substring = "sub"; boolean foundIt = false; int max = searchMe.length() - substring.length(); test: for (int i = 0; i <= max; i++) { int n = substring.length(); int j = i; int k = 0; while (n-- != 0) { if (searchMe.charAt(j++) != substring.charAt(k++)) { continue test; } } foundIt = true; break test; } System.out.println(foundIt ? "Found it" : "Didn't find it"); } }
A visszaadott rtk adattpusa meg kell, hogy egyezzen a fggvnyben deklarlt visszatrsi rtk tpusval. Ha a fggvnyt void-nak deklarltuk, hasznljuk a return azon alakjt, ami nem ad vissza rtket:
return;
60. oldal Mi a while utasts? Mi a ciklusmag? Mit jelent, hogy a while elltesztel ciklus? Hogyan lehet htultesztel while ciklust rni? Mi a for ciklus? Ell-vagy htultesztel a for ciklus? Mit jelent az egymsba gyazott ciklus?
Mit neveznk cmknek, hogyan cmkzhetnk utastsokat? Ismertesse a tbbszrs elgazs ksztsre alkalmas utastst! Ismertesse a break utasts hasznlatt! Mire hasznlhatjuk a continue utastst?
61. oldal
amely v, hnap s nap szmrtkek alapjn kiszmolja, hogy az v hnyadik napjrl van sz. Figyelni kell a szkvekre is! rjon programot, amely kirja egy egsz szm szmjegyeinek sszegt. tlet: az utols jegy maradkkpzssel knnyedn megkaphat, utna pedig osztssal el lehet tvoltani az utols szmjegyet. Pl. a szm 123. Ekkor az utols szmjegy 3 (a 10-es oszts maradka), majd az utols jegy eldobsa a 10-el val osztssal oldhat meg: 123/10 = 12.
62. oldal
7. Objektumok hasznlata
Egy tipikus Java program sok objektumot hoz ltre, amik zenetek kldsvel hatnak egymsra. Ezeken keresztl tud egy program klnbz feladatokat vgrehajtani. Amikor egy objektum befejezi a mkdst, az erforrsai felszabadulnak, hogy ms objektumok hasznlhassk azokat. A kvetkez CreateObjectDemo program hrom objektumot hoz ltre: egy Point s kt Rectangle objektumot:
public class CreateObjectDemo { public static void main(String[] args) { Point originOne = new Point(23, 94); Rectangle rectOne = new Rectangle(originOne, 100, 200); Rectangle rectTwo = new Rectangle(50, 100); System.out.println("Width of rectOne: " + rectOne.width); System.out.println("Height of rectOne: " + rectOne.height); System.out.println("Area of rectOne: " + rectOne.area()); rectTwo.origin = originOne; System.out.println("X Position + rectTwo.origin.x); System.out.println("Y Position + rectTwo.origin.y); rectTwo.move(40, 72); System.out.println("X Position + rectTwo.origin.x); System.out.println("Y Position + rectTwo.origin.y); of rectTwo: " of rectTwo: " of rectTwo: " of rectTwo: "
} }
7.Objektumok hasznlata
63. oldal
Az els sor egy Point osztlybl, a msodik s harmadik a Rectangle osztlybl hoz ltre objektumot. Minden sor a kvetkezket tartalmazza: Deklarci: Az = eltti rszek a deklarcik, amik a vltozkhoz rendelik hozz az objektum tpusokat. Pldnyosts: A new sz egy Java opertor, ami ltrehoz egy objektumot. Inicializci: A new opertort egy konsturktorhvs kveti. Pl. a Point (23,94) meghvja a Point egyetlen konstruktort. A konstruktor inicializlja az j objektumot.
Ez kzli a fordtval, hogy a name tagot hasznljuk egy adatra hivatkozshoz, aminek a tpusa type. A Java nyelv a vltoz tpusokat kt f kategrira osztja: egyszer tpusok s hivatkozs (referencia) tpusok. Az egyszer tpusok (byte, short, int, long, char, float, double, boolean) mindig egyszer rtkeket tartalmaznak az adott tpusbl. A hivatkozs tpusok azonban nmileg sszetettebbek. A kvetkez mdok brmelyike szerint deklarlhatk: A deklarlt tpus megegyezik az objektum osztlyval:
MyClass myObject = new MyClass();
Ha ezt hasznljuk, a myObject rtke automatikusan null lesz, amg egy objektum tnylegesen ltre nem lesz hozva s hozzrendelve. A vltoz deklarci nmagban nem hoz ltre objektumot. Ehhez a new opertort kell hasznlni. Amg egy vltoz nem tartalmaz hivatkozst objektumra, null hivatkozst tartalmaz. Ha az originOne vltozt ilyen mdon deklarljuk, akkor a kvetkezkpen illusztrlhat (vltoz neve a hivatkozssal, ami nem mutat sehova):
Objektum pldnyostsa
A new opertor egy pldnyt hoz ltre egy osztlybl, s memriaterletet foglal az j objektumnak. A new opertor utn szksg van egy osztlyra, ami egyben egy konstruktor hvst is elr. A konstruktor neve adja meg, hogy melyik osztlybl kell pldnyt ltrehozni. A konstruktor inicializlja az j objektumot.
64. oldal
A new opertor egy hivatkozst ad vissza a ltrehozott objektumra. Gyakran ezt a hivatkozst hozzrendeljk egy vltozhoz. Ha a hivatkozs nincs hozzrendelve vltozhoz, az objektumot nem lehet majd elrni, miutn a new opertort tartalmaz utasts vgrehajtdott. Az ilyen objektumot nvtelen objektumnak is szoktuk nevezni.
Megjegyzs: A nvtelen objektumok nem olyan ritkk, mint ahogy azt gondolhatnnk. Pl. egy tmbbe vagy trolba helyezett objektum is nvtelen, hiszen nincs sajt, nvvel elltott hivatkozsa.
Objektum inicializlsa
A Point osztly kdja:
public class Point { public int x = 0; public int y = 0; public Point(int x, int y) { this.x = x; this.y = y; }
Ez az osztly egy konstruktort tartalmaz. A konstruktornak ugyanaz a neve, mint az osztlynak, s nincs visszatrsi rtke. A Point osztly konstruktora kt egsz tpus paramtert kap: (int x, int y). A kvetkez utasts a 23 s 94 rtkeket adja t paramterknt:
Point originOne = new Point(23, 94);
7.Objektumok hasznlata
public Rectangle(Point p, int w, int h) { origin = p; width = w; height = h; } public void move(int x, int y) { origin.x = x; origin.y = y; } public int area() { return width * height; } }
65. oldal
Akrmelyik konstruktorral kezdeti rtket adhatunk a tglalapnak, klnbz szempontok szerint: a koordinti (origin); szlessge s magassga; mind a hrom; vagy egyik sem. Ha egy osztlynak tbb konstruktora van, mindnek ugyanaz a neve, de klnbz szm vagy klnbz tpus paramterekkel rendelkezik. A Java platform a konstruktort a paramterek szma s tpusa alapjn klnbzteti meg. A kvetkez kdnl a Rectangle osztlynak azt a konstruktort kell meghvnia, ami paramterknt egy Point objektumot s kt egszet vr:
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Ez a hvs inicializlja a tglalap origin vltozjt az originOne-nal (originOne rtkt veszi fel az origin vltoz), ami egy Point objektumra hivatkozik, a width rtke 100-zal lesz egyenl, a height rtkt 200-zal. Most mr kt hivatkozs van ugyanarra a Point objektumra; egy objektumra tbb hivatkozs is lehet:
A kvetkez sor kt egsz tpus paramterrel rendelkez konstruktort hvja meg, amik a width s height rtkei. Ha megnzzk a konstruktor kdjt, ltjuk, hogy ltrehoz egy j Point objektumot, aminek az x s y rtke is nulla lesz:
Rectangle rectTwo = new Rectangle(50, 100);
66. oldal
Ha egy osztly nem deklarl egy konstruktort se, akkor a Java platform automatikusan szolgltat egy paramter nlkli (alaprtelmezett, default) konstruktort, ami nem csinl semmit. gy minden osztlynak van legalbb egy konstruktora.
ltalnos formja: Amikor egy vltoz az rvnyessgi krn bell van itt az osztlyon bell , hasznlhat az egyszer hivatkozs is. A hivatkozs els rsze egy objektum referencia kell, hogy legyen. Lehet hasznlni egy objektum nevt, vagy egy kifejezst, ami egy objektum-hivatkozssal tr vissza. A new opertor egy hivatkozssal tr vissza, ezzel hozzfrhetnk egy j objektum vltozihoz:
int height = new Rectangle().height;
Miutn ez vgrehajtdik, tbb nem lehet hivatkozni a ltrejtt Rectangle objektumra, mert nem troltuk el a hivatkozst egy vltozban.
A tagvltozk hozzfrhetsge
Konvenci szerint egy objektum tagvltozit ms objektum vagy osztly kzvetlenl nem mdosthatja, mert lehet, hogy rtelmetlen rtk kerlne bele. Ehelyett, hogy a vltoztatst megengedje, egy osztly biztosthat metdusokat, amiken keresztl ms objektumok megnzhetik, illetve mdosthatjk a vltozit. Ezek a metdusok biztostjk, hogy a megfelel tpus kerljn a vltozba. A msik elnyk, hogy az osztly megvltoztathatja a vltoz nevt s tpust anlkl, hogy hatssal lenne a klienseire. Azonban nha szksg lehet arra, hogy kzvetlen hozzfrst biztostsunk a vltozkhoz. Ezt gy tehetjk meg, hogy a public szt rjuk eljk, a private-tel pedig tilthatjuk a kls hozzfrst.
7.3. Metdushvs
Itt is hasznlhat ugyanaz a forma, mint a vltozknl. A metdus neve utni zrjelekben adhatk meg a paramterek. Ha nincsenek, res zrjelet kell rnunk.
objectReference.methodName(argumentList); objectReference.methodName();
A kifejezs egy hivatkozst ad vissza a Rectangle objektumra. A pont utn rva a metdus nevt, az vgrehajtdik az j Rectangle objektumon.
7.Objektumok hasznlata
67. oldal
Nhny eljrsnak van visszatrsi rtke, ezrt ezek kifejezsekben is hasznlhatak. A visszaadott rtket vltozhoz rendelhetjk:
int areaOfRectangle = new Rectangle(100, 50).area();
Metdusok hozzfrhetsge
Ugyangy mkdik, mint a vltozkhoz val hozzfrs. A metdusokhoz val hozzfrst is a public kulcsszval engedlyezhetjk ms objektumoknak, a private-tel pedig tilthatjuk.
A szemtgyjt
A szemtgyjt peridikusan felszabadtja a mr nem hasznlt objektumok ltal foglalt memrit. Automatikusan vgzi a dolgt, br nha szksg lehet r, hogy kzvetlen meghvjuk. Ezt a System osztly gc metdusval tehetjk meg. Olyankor lehet r szksg, ha egy kdrsz sok szemetet hoz ltre, vagy egy kvetkez kdrsznek sok memrira van szksge. ltalban elegend hagyni, hogy magtl fusson le.
Megjegyzs: Egyes fejlesztk a Java egyik gyenge pontjnak tartjk a memriakezelst. Aki gy gondolja, hogy tud jobb megoldst a Sun programozi ltal ltrehozottnl, akr a sajtjt is hasznlhatja.
7.5. Takarts
Mieltt egy objektum a szemtgyjtbe kerlne, a gyjt lehetsget ad az objektumnak, hogy kitakartson maga utn gy, hogy meghvja az objektum finalize metdust. A finalize metdus az Object osztly tagja, ami minden osztly szlosztlya, a hierarchia tetejn ll. Egy osztly fellrhatja a finalize metdust, ha szksges, de ekkor a metdus legvgn meg kell hvnia a super.finalize() fggvnyt.
A kvetkez kd ltrehoz egy Point s egy Rectangle objektumot. Hny referencia hivatkozik az objektumokra a kvetkez kdrszlet lefutsa utn? Ha lefut a szemtgyjts, melyik objektum fog megsznni?
... Point point = new Point(2,4); Rectangle rectangle = new Rectangle(point, 20, 20); point = null; ...
8.Karakterek s sztringek
69. oldal
8. Karakterek s sztringek
8.1. A Character osztly
Egy Character tpus objektum egyetlen karakter rtket tartalmaz. A Character objektumot az egyszer char vltoz helyett hasznljuk, amikor objektum szksges, pldul: amikor tadunk egy karakter rtket egy metdusnak, ami megvltoztatja az rtket, vagy amikor egy karakter rtket helyeznk el egy adattrolban, mint pldul egy ArrayList-ben, ami objektumokat tud csak trolni, primitv rtkeket nem.
Megjegyzs: a burkol (csomagol) osztlyokrl a kvetkez fejezetben lesz sz.
A kvetkez pldaprogram (CharacterDemo) ltrehoz nhny Character objektumot, s megjelent rluk nhny informcit. A Character osztlyhoz tartoz kd az albbiakban lthat:
public class CharacterDemo { public static void main(String args[]) { Character a = new Character('a'); Character a2 = new Character('a'); Character b = new Character('b'); int difference = a.compareTo(b); if (difference == 0) { System.out.println("a is equal to b."); } else if (difference < 0) { System.out.println("a is less than b."); } else if (difference > 0) { System.out.println("a is greater than b."); } System.out.println("a is " + ((a.equals(a2)) ? "equal" : "not equal") + " to a2."); System.out.println("The character " + a.toString() + " is " + (Character.isUpperCase(a.charValue()) ? "upper" : "lower") + "case.");
} }
A fenti pldban a Character.isUpperCase(a.charValue()) fggvny adja az a nev Character objektum kdjt. Ez azrt van, mert az isUppercase metdus char tpus paramtert vr. Ha a JDK 5.0-t vagy jabb fejlesztkrnyezetet hasznlunk, akkor ennek a metdusnak megadhatjuk a Character tpus objektumot is:
Character.isUpperCase(a)
A CharacterDemo program a Character osztly albbi konstruktorait, illetve metdusait hvja meg:
70. oldal
Character(char): A Character osztly egyetlen konstruktora, amely ltrehoz egy Character objektumot, melynek rtkt a paramterben adjuk meg, ltrehozs utn a Character objektum rtke nem vltozhat. compareTo(Character): sszehasonlt kt Character objektumban trolt rtket, azt az objektumot, ami meghvta (a pldban a), s azt, ami a paramterben van (b). Visszaad egy egsz szmot, ami jelzi, hogy az objektum rtke kisebb, egyenl, vagy nagyobb, mint a paramterben megadott rtk. equals(Object): 2 Character objektumot hasonlt ssze. True rtkkel tr vissza, ha a kt rtk egyenl. toString(): Stringg konvertlja az objektumot, a sztring 1 karakter hossz lesz, s a Character objektum rtkt tartalmazza. charValue(): Megadja az objektum rtkt egyszer char rtkknt. isUpperCase(char): Meghatrozza, hogy az egyszer char rtk nagybet-e. boolean isUpperCase(char) boolean isLowerCase(char) char toUpperCase(char) char toLowerCase(char) boolean isLetter(char) boolean isDigit(char) boolean isLetterOrDigit(char) boolean isWhitespace(char) boolean isSpaceChar(char) boolean isJavaIdentifierStart(char) boolean isJavaIdentifierPart(char)
A kvetkez pldaprogram neve StringsDemo, amely megfordtja egy sztring karaktereit. A program hasznlja a String s StringBuilder osztlyokat is. Ha a JDK 5.0-s vlto-
8.Karakterek s sztringek
71. oldal
zatnl rgebbit hasznl, a StringBuilder elfordulsait le kell cserlni StringBuffer-re, s a program mkdni fog.
public class StringsDemo { public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); StringBuilder dest = new StringBuilder(len); for (int i = (len - 1); i >= 0; i--) { dest.append(palindrome.charAt(i)); } System.out.println(dest.toString()); } }
String-eket gy is elllthatunk, min brmilyen ms Java objektumot: a new kulcssz s a konstruktor segtsgvel. A String osztly tbb konstruktort szolgltat, amelyekkel bellthatjuk a String kezdrtkt, klnbz forrsokat hasznlva, mint pldul karakter tmbt, byte tmbt, StringBuffert, vagy StringBuildert. A kvetkez tblzat a String osztly konstruktorait tartalmazza: String() String(byte[]) String(byte[], int, int) String(byte[], int, int, String) String(byte[], String) String(char[]) String(char[], int, int) String(String) String(StringBuffer) String(StringBuilder) res String-et hoz ltre. Bjttmb tartalma alapjn jn ltre. Lehetsg van egy egsz kezdindex s hossz megadsra rszintervallum figyelembevtelhez, illetve meg lehet adni karakterkdolst is. Karaktertmb egsze vagy csak egy rsze alapjn jn ltre. Msik String msolatt hozza ltre. StringBuffer tartalma alapjn jn ltre. StringBuilder tartalma alapjn jn ltre.
Ha StringBuffer-t, vagy StringBuilder-t hozunk ltre, mindig hasznlnunk kell a new opertort. Mivel a kt osztlynak azonosak a konstruktorai, a kvetkez tblzat csak a StringBuffer osztly konstruktorait tartalmazza: StringBuffer() StringBuffer(CharSequence) StringBuffer(int) StringBuffer(String) A StringsDemo programban egy dest nev StringBuildert hozunk ltre, azt a konstruktort hasznlva, amely a puffer kapacitst lltja be:
String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); StringBuilder dest = new StringBuilder(len);
A kd ltrehoz egy StringBuildert, melynek kezdeti kapacitsa megegyezik a palindrome nev String hosszval. Ez csak a memriafoglalst biztostja a dest szmra, mert ennek mrete pontosan elegend lesz a bemsoland karakterek szmra. A StringBuffer vagy StringBuilder kapacitsnak inicializlsval egy elfogadhat mretre minimalizlhatjuk a memriafoglalsok szmt, amivel sokkal hatkonyabb tehetjk programunkat, mert a memriafoglals elg kltsges mvelet.
Megjegyzs: Ha egy StringBuilder vagy StringBuffer objektum mret nvelse sorn a szabad kapacitsa elfogy, akkor egy j, ktszer akkora memriaterlet kerl lefoglalsra, ahov a rgi tartalom tmsolsra kerl. Ebbl is ltszik, hogy ha tudjuk, rdemes pontosan (vagy legalbb becslten) megadni a szksges kapacitst.
A Stringek hossza
Azon metdusokat, amelyeket arra hasznlunk, hogy informcit szerezznk egy objektumrl, olvas (vagy hozzfr) metdusoknak nevezzk. Egy ilyen String-eknl, StringBuffer-eknk s StringBuilder-eknl hasznlhat metdus a length, amely visszaadja az objektumban trolt karakterek szmt. Miutn az albbi kt sor vgrehajtdik, a len vltoz rtke 17 lesz:
String palindrome = "Dot saw I was Tod"; int len = palindrome.length();
A length mellett StringBuffer s StringBuilder osztlyok esetn hasznlhatjuk mg a capacity metdust is, amely a lefoglalt terlet mrett adja vissza, s nem a hasznlt terletet. Pldul a dest nev StringBuilder kapacitsa a StringDemo programban nem vltozik, mg a hossza minden karakter beolvassa utn n egyel. A kvetkez bra mutatja a dest kapacitst s hosszt, miutn kilenc karakter hozz lett fzve.
8.Karakterek s sztringek
73. oldal
A StringBuffer vagy StringBuilder hossza a benne trolt karakterek szma, mg kapacitsa az elre lefoglalt karakterhelyek szma. A String osztly esetn a capacity metdus nem hasznlhat, mert a String tartalma nem vltozhat meg.
Az indexels 0-val kezddik, teht a 9-es index karakter az 0, mint ahogy a kvetkez bra is mutatja:
Hasznljuk a charAt fggvnyt, hogy megkapjuk a megfelel index karaktert. Az bra is mutatja, hogy hogyan lehet kiszmtani egy String-ben az utols karakter indext. Ki kell vonni a length() fggvny visszatrsi rtkbl 1-et. Ha tbb, mint egy karaktert szeretnnk megkapni a String-bl, StringBuffer-bl vagy StringBuilder-bl, akkor a substring fggvnyt kell hasznlni. A substring-nek kt fajtja van, amit az albbi tblzat is mutat: String substring(int) String substring(int, int) Visszatrsi rtk egy j String, ami az eredeti sztring rsznek msolata. Az els paramter az els karakter indexe (ahonnan krjk a karaktereket), a msodik int paramter pedig az utols karakter indexe (ameddig krjk)-1. A substring hosszt megkapjuk, ha a msodik paramter rtkbl kivonjuk az els paramter rtkt. Ha nem adjuk meg a msodik paramtert, akkor az eredeti String vgig trtnik a msols.
Az albbi forrskd a Niagara tkrmondatbl ad vissza egy rszletet, ami a 11. indextl a 15. indexig tart, ez pedig a roar kifejezs:
String anotherPalindrome = "Niagara. O roar again!"; String roar = anotherPalindrome.substring(11, 15);
74. oldal int lastIndexOf(int) int indexOf(int, int) int lastIndexOf(int, int) int indexOf(String) int lastIndexOf(String) int indexOf(String, int) int lastIndexOf(String, int)
Visszaadja az els (utols) elfordulkarakter indext, az indextl elre (visszafele) keresve. Visszaadja az els (utols) elfordul String indext. Visszaadja a String els (utols) elfordulsnak indext, a megadott indextl elre (visszafele) keresve.
A StringBuffer s a StringBuilder osztlyok nem tmogatjk az indexOf s a lastIndexOf fggvnyeket. Ha hasznlni szeretnnk ezeket a metdusokat, elszr String-g kell konvertlnunk az objektumot a toString fggvny segtsgvel.
Megjegyzs: A metdusok az albbi Filename osztlyban nem minden hibt kezelnek, s felttelezik, hogy az paramter tartalmazza a teljes knyvtr tvonalat, s a fjlnevet kiterjesztssel.
public class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } public String filename() { int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); }
75. oldal
Ahogy a fenti plda is mutatja, az extension metdus a lastIndexOf fggvnyt hasznlja, hogy megtallja az utols pontot a fjlnvben. Ha a fjlnvben nincs pont, a lastIndexOf visszatrsi rtke -1, s a substring metdus StringIndexOutOfBoundsException kivtelt dob. Ha a pont karakter (.) az utols karakter a String-ben, akkor ez egyenl a String hosszval, ami egyel nagyobb, mint a legnagyobb index a String-ben (mivel az indexels 0-val kezddik).
Sztringek mdostsa
A String osztly sokfle metdust tartalmaz a String-ek mdostshoz. Termszetesen a String objektumokat nem tudja mdostani, ezek a metdusok egy msik String-et hoznak ltre, ez tartalmazza a vltoztatsokat. Ezt kvethetjk az albbi tblzatban. String concat(String) A String vghez lncolja a String paramtert. Ha az paramter hossza 0, akkor az eredeti String objektumot adja vissza. Felcserli az sszes els paramterknt megadott ka-
76. oldal
Java programozs (1.3. verzi) raktert a msodik paramterben megadottra. Ha nincs szksg cserre, akkor az eredeti String objektumot adja vissza.
Eltvoltja az elvlaszt karaktereket a String elejrl s a vgrl. Konvertlja a String-et kis, vagy nagybetsre. Ha nincs szksg konverzira, az eredeti String-et adja vissza.
me egy rvid program (BostonAccentDemo), ami a replace metdussal egy String-et fordt Bostoni dialektusra:
public class BostonAccentDemo { private static void bostonAccent(String sentence) { char r = 'r'; char h = 'h'; String translatedSentence = sentence.replace(r, h); System.out.println(translatedSentence); } public static void main(String[] args) { String translateThis = "Park the car in Harvard yard."; bostonAccent(translateThis); } }
A StringBuffer-ek mdostsa
A StringBuffer-ek tartalma mdosthat. A kvetkez tblzat sszefoglalja a StringBuffer-ek mdostshoz hasznlhat metdusokat. Azonos metdusokat tartalmaz a StringBuilder osztly is, de StringBuilder-eket is ad vissza, ezrt ezeket kln nem soroljuk fel. StringBuffer append(boolean) StringBuffer append(char) StringBuffer append(char[]) StringBuffer append(char[], int, int) StringBuffer append(double) StringBuffer append(float) StringBuffer append(int) StringBuffer append(long) StringBuffer append(Object) StringBuffer append(String) StringBuffer delete(int, int) StringBuffer deleteCharAt(int) StringBuffer insert(int, boolean) Hozzfzi a megadott paramtert a StringBuffer-hez. Az adat String-g konvertldik, mieltt a hozzfzs megtrtnne.
8.Karakterek s sztringek StringBuffer insert(int, char) StringBuffer insert(int, char[]) StringBuffer insert(int, char[], int, int) StringBuffer insert(int, double) StringBuffer insert(int, float) StringBuffer insert(int, int) StringBuffer insert(int, long) StringBuffer insert(int, Object) StringBuffer insert(int, String) StringBuffer replace(int, int, String) void setCharAt(int, char) StringBuffer reverse()
77. oldal Az els egsz tpus paramter jelzi az adat indext, ahova a beilleszts trtnik. Az adat String-g konvertldik, mieltt a beilleszts megtrtnik.
Az append metdusra mr lttunk pldt a StringsDemo programban, a fejezet elejn. Az albbi InsertDemo program bemutatja az insert metdus hasznlatt. Beilleszt egy String-et a StringBuffer-be:
public class InsertDemo { public static void main(String[] args) { StringBuffer palindrome = new StringBuffer( "A man, a plan, a canal; Panama."); palindrome.insert(15, "a cat, "); System.out.println(palindrome); } }
A program kimenete:
A man, a plan, a cat, a canal; Panama.
Az ltalunk megadott index utni helyre kerl beillesztsre az adat. A StringBuffer elejre val beillesztshez a 0 indexet kell hasznlni. A vghez val beilleszts esetn az index rtke megegyezik a StringBuffer jelenlegi hosszval, vagy hasznljuk a hozzfzst (append) is. Ha a mvelet miatt tlsgosan megn a StringBuffer mrete, akkor az tbb memrit fog lefoglalni. Mivel a memria lefoglals kltsges, ezrt lehetleg gy kell elkszteni a kdot, hogy megfelelen be legyen lltva a StringBuffer mrete.
A String-ek s a fordt
A fordt felhasznlja a String s a StringBuffer osztlyokat a httrben, hogy a Stringliterlokat s klnbz sszefzseket kezelje. A String-et idzjelek kztt adhatjuk meg:
"Hello World!"
String-literlokat brhol hasznlhatunk String pldnyknt. Pldaknt, a System.out.println paramternek String-literlt adunk meg:
System.out.println("Might I add that you look lovely today.");
A kvetkez plda egyenrtk az elzvel, de nem olyan hatkony. Kt azonos String-et kszt, hasznlata kerlend:
String s = new String("Hola Mundo"); //ne hasznljuk
A fordt konvertlja a nem String rtket (a pldban int 1-et) String objektumm, mieltt az sszefzst elvgzi.
A StringTokenizer objektum nyilvn tartja, hogy a feldolgozs a String melyik pontjn jr. A konstruktornak megadhatunk a szvegen kvl egy elvlaszt-karaktereket tartalmaz String-et is, ekkor az alaprtelmezett " \t\n\r\f" elvlasztk helyett ezt fogja az objektum figyelembe venni.
8.Karakterek s sztringek Mit jelent, hogy a String nem megvltoztathat? Hogyan lehet egy String-nek kezdrtket adni? Mire val a String indexOf metdusa? Mire val String substring metdusa? Mi a klnbsg a StringBuilder, a StringBuffer s a String kztt?
79. oldal
Melyik kifejezs rtke lesz logikailag igaz? "john" == "john" "john".equals("john") "john" = "john" "john".equals(new Button("john"))
Melyik fordul le? "john" + " was " + " here" "john" + 3 3+5 5 + 5.5
Ha a Java tartalm s String-ben keressk a v bet pozcijt (a 2-t), akkor melyik metdushvssal kapjuk ezt meg? mid(2,s); s.charAt(2); s.indexOf('v'); indexOf(s,'v');
9.Szmok
81. oldal
9. Szmok
A kvetkez bra bemutatja a Jva platformon rendelkezsre ll szm osztlyok hierarchijt.
Ezen kvl a platform tartalmazza a Boolean, Void s Character osztlyokat, amelyek a szm osztlyokkal egytt csomagol (vagy burkol) osztlyoknak hvunk. Taln meglep, hogy mirt nlklzhetetlenek a csomagol osztlyok, de ezt majd ltni fogjuk a ksbbiekben.
Tovbb a BigInteger s BigDecimal kiterjeszti a hagyomnyos adattpusokat, s tetszleges pontossg alkalmazst engedi meg. A tbbi osztly a java.lang csomag rsze, a BigDecimal s a BigInteger a java.math csomagban van. Kvetkezzen egy plda (NumberDemo), amely ltrehoz kt Float s egy Double objektumot, s utna hasznlja a compareTo s az equalTo metdusokat sszehasonltsra.
public class NumberDemo { public static void main(String args[]) { Float floatOne = new Float(14.78f - 13.78f); Float floatTwo = Float.valueOf("1.0"); Double doubleOne = new Double(1.0); int difference = floatOne.compareTo(floatTwo);
82. oldal
} }
A kvetkez tblzat bemutatja azon pldnymetdusokat, melyeket a Number osztly sszes leszrmazott osztlya tartalmaz, beleszmtva az sszehasonlt s egyenlsgvizsgl metdusokat, melyek az elz pldban szerepeltek. byte byteValue() short shortValue() int intValue() long longValue() float floatValue() double doubleValue() int compareTo(Integer) int compareTo(Object) Konvertlja a szm objektum rtkt egy egyszer adattpuss (short, long, float, doube)
sszehasonltja a szm objektumot a paramterrel. A metdus nullnl kisebb, nulla, vagy nullnl nagyobb rtkkel tr vissza attl fggen, hogy az objektum rtke kisebb, egyenl vagy nagyobb a hasonltott objektummal. Meghatrozza, hogy a szm objektum egyenl-e a paramterrel. Klnbz tpus szm objektumok a matematikai rtkktl fggetlenl sosem egyenlek.
boolean equals(Object)
A szm csomagol osztlyok tbb hasznos publikus s statikus konstanst tartalmaznak. Ezekre gy tudunk hivatkozni kifejezsekben, hogy az osztly nevt s a konstanst egy ponttal vlasztjuk el, pl. Integer.MIN_VALUE. A kvetkez tblzat felsorol tbb hasznos konstanst a Float s Double osztlyokbl Float.NaN Double.NaN Nem szm. Ez az alaprtelmezett rtk, ha egy kifejezs rtke matematikailag nem rtelmezhet.
9.Szmok Float.NEGATIVE_INFINITY Double.NEGATIVE_INFINITY Float.POSITIVE_INFINITY Double.POSITIVE_INFINITY Negatv vgtelen rtk Pozitv vgtelen rtk
83. oldal
} }
A kvetkezkben a program kimenett lthatjuk, amely a 4.5 s a 87.2-t hasznlta parancssori paramternek:
a a a a a + * / % b b b b b = = = = = 91.7 -82.7 392.4 0.0516055 4.5
84. oldal
public class ToStringDemo { public static void main(String[] args) { double d = 858.48; String s = Double.toString(d); int dot = s.indexOf('.'); System.out.println(s.substring(0, dot).length() + " digits before decimal point."); System.out.println(s.substring(dot+1).length() + " digits after decimal point."); } }
A program kimenete:
3 digits before decimal point. 2 digits after decimal point.
Pnznem formtum
Gazdasgi alkalmazs esetn pnzsszegek kezelsre is szksg van. Ennek alkalmazst mutatja a kvetkez kdrszlet:
Double currency = new Double(9876543.21); NumberFormat currencyFormatter; String currencyOut; currencyFormatter = NumberFormat.getCurrencyInstance(); currencyOut = currencyFormatter.format(currency); System.out.println(currencyOut);
9.Szmok
85. oldal
A szzalk formtum
Szzalk formban val kirshoz szintn a helyi belltsokat figyelembe vev objektumot kapunk a getPercentInstance metdus segtsgvel:
Double percent = new Double(0.75); NumberFormat percentFormatter; String percentOut; percentFormatter = NumberFormat.getPercentInstance(); percentOut = percentFormatter.format(percent); System.out.println(percentOut);
Az els paramter azt hatrozza meg, hogy a tovbbi paramterek milyen formtumban kerljenek kirsra. A sokfle lehetsg szerencsre alaposan dokumentlva van az API specifikciban. Nzzk a kvetkez pldt:
Calendar c =...; String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY",c);
A formtum meghatrozs egyszer. Hrom van bellk: %1$tm, %1$te, s %1$tY, amelyek mindegyike elfogadja a c nev Calendar objektumot. A formtum meghatrozs a kvetkezket jelenti: % jelzi a formtum meghatrozs kezdett 1$ az els tovbbi paramter jelzse tm jelenti a hnapot te jelenti a hnap napjt tY jelenti az vet
Sablon ksztse
A DecimalFormat osztlyban meghatrozhatjuk egy String minta segtsgvel a specilis kirsi formtumot. A minta fogja meghatrozni, hogy hogyan nzzen ki a megformzott szm. A kvetkez plda kszt egy formzt, ami tadja a String mintt a DecimalFormat konstruktornak. A format metdus tvesz egy Double rtket, s formzott String-gel tr vissza.
DecimalFormat myFormatter = new DecimalFormat(pattern); String output = myFormatter.format(value); System.out.println(value + " " + pattern + " " + output);
Java programozs (1.3. verzi) magyarzat A ketts kereszt (#) utal a szmjegyre, a vessz a csoportosts helyt jelzi, s a pont jelzi a tizedespont helyt. A value-nak hrom szmjegye van a tizedes pont utn, de a pattern-nek csak kett. A format metdus ezt gy oldja meg, hogy felkerekti a szmot.
123456.789 ###,###.###
123456.789 ###.##
123456.79
123.78
000000.000
000123.780 A pattern itt a ketts kereszt (#) helyett kezd s soron kvetkez nullkat definil. $12,345.67 Az els karakter a pattern-ben a dollr jel ($). Ez annyit jelent, hogy rgtn a balrl els szmjegy el kerl. A pattern beilleszti a Japn pnzt, a yen-t () az Unicode rtkvel : 00A5.
12345.67
$###,###.###
12345.67
\u00A5###,###.### 12,345.67
9.Szmok
87. oldal
9.5. Aritmetika
A Java programozsi nyelv tmogatja az alapvet aritmetikai szmtsokat az aritmetikai opertorokkal egytt: +, -, *, /, s %. A java.lang csomagban a Java platform biztostja a Math osztlyt. Ez olyan metdusokat s vltozkat biztost, amik segtsgvel mr magasabb rend matematikai szmtsok is elvgezhetk, mit pldul egy szg szinusznak kiszmtsa, vagy egy szm bizonyos hatvnyra emelse. A Math osztly metdusai osztlymetdusok, teht kzvetlenl az osztly nevvel kell ket meghvni, pldul gy:
Math.round(34.87);
A Math osztly metdusai kzl elsknt klnbz alapvet matematikai fggvnyeket nzzk meg, mint pldul egy szm abszolt rtknek kiszmtsa vagy egy szm kerektse valamelyik irnyban. A kvetkez tblzat ezeket a metdusokat tartalmazza: double abs(double) float abs(float) int abs(int) long abs(long) double ceil(double) A paramterknt kapott paramter abszolt rtkvel tr vissza.
A legkisebb double rtkkel tr vissza, ami nagyobb vagy egyenl a paramterrel, s egyenl egy egsz szmmal. (felfel kerekt)
double floor(double)
A legnagyobb double rtkkel tr vissza, ami kisebb vagy egyenl a paramterrel, s azonos egy egsz szmmal. (lefel kerekt)
double rint(double)
A paramterhez legkzelebb ll double rtkkel tr vissza, s azonos egy egsz szmmal. (a legkzelebbi egszhez kerekt)
A legkzelebbi long vagy int rtket adja vissza, ahogy azt a metdus visszatrsi rtke jelzi.
A program kimenetei:
88. oldal
The The The The
Tovbbi kt alapvet metdus tallhat a Math osztlyban. Ezek a min s a max. Az albbi tblzat mutatja be a min s max metdusok klnbz formit, amik kt szmot hasonltanak ssze, s a megfelel tpus rtkkel trnek vissza. double min(double, double) float min(float, float) int min(int, int) long min(long, long) double max(double, double) float max(float, float) int max(int, int) long max(long, long) A kt paramterbl a kisebbel trnek vissza.
} }
A Math osztly kvetkez metdusai a hatvnyozssal kapcsolatosak. Ezen kvl megkaphatjuk az e rtkt a Math.E hasznlatval. double exp(double) double log(double) double pow(double, double) double sqrt(double) A szm exponencilis rtkvel tr vissza. A szm termszetes alap logaritmusval tr vissza. Az els paramtert a msodik paramternek megfelel hatvnyra emeli. A paramter ngyzetgykvel tr vissza.
A kvetkez ExponentialDemo program kirja az e rtkt, majd meghvja egyenknt a fenti tblzatban lthat metdusokat egy szmra:
public class ExponentialDemo { public static void main(String[] args) { double x = 11.635; double y = 2.76;
9.Szmok
89. oldal
System.out.println("Az e rtke: " + Math.E); System.out.println("exp(" + x + ") is " + Math.exp(x)); System.out.println("log(" + x + ") is " + Math.log(x)); System.out.println("pow(" + x + ", " + y + ") is " + Math.pow(x, y)); System.out.println("sqrt(" + x + ") is " + Math.sqrt(x));
Az ExponentialDemo kimenete:
Az e rtke: 2.71828 exp(11.635) is 112984 log(11.635) is 2.45402 pow(11.635, 2.76) is 874.008 sqrt(11.635) is 3.41101
A Math osztly egy sor trigonometrikus fggvnyt is knl, ezek a kvetkez tblzatban vannak sszefoglalva. A metduson thalad szgek radinban rtendk. Radinbl fokk, s onnan visszakonvertlsra kt fggvny ll rendelkezsnkre: toDegrees s toRadians. Elbbi fokk, utbbi radinn konvertl. A Math.PI fggvny meghvsval a PI rtkt kapjuk meg a lehet legpontosabban. double sin(double) double cos(double) double tan(double) double asin(double) double acos(double) double atan(double) double atan2(double) double toDegrees(double) double toRadians(double) Egy double szm szinuszval tr vissza. Egy double szm koszinuszval tr vissza. Egy double szm tangensvel tr vissza. Egy double szm arc szinuszval tr vissza. Egy double szm arc koszinuszval tr vissza. Egy double szm arc tangensvel tr vissza. Derkszg koordintkat konvertl (b, a) polriss (r, thta). A paramtert radinn vagy fokk konvertljk, a fggvnyek adjk magukat.
A kvetkez TrigonometricDemo program hasznlja a fenti tblzatban bemutatott szszes metdust, hogy klnbz trigonometrikus rtkeket szmoljon ki a 45 fokos szgre:
public class TrigonometricDemo { public static void main(String[] args) { double degrees = 45.0; double radians = Math.toRadians(degrees);
90. oldal
A program kimenetei:
value of pi is 3.141592653589793 sine of 45.0 is 0.8060754911159176 cosine of 45.0 is -0.5918127259718502 tangent of 45.0 is -1.3620448762608377
Megjegyezzk, hogy a NaN akkor jelenik meg, amikor az eredmny matematikailag nem definilt. A Double s a Float osztlyok is tartalmazzk a NaN konstanst. sszehasonltva a visszatrsi rtket az egyik ilyen konstanssal, a programunk el tudja dnteni, hogy a visszaadott rtk rvnyes-e. Ilyen mdon a programunk elfogadhatan tud reaglni, ha egy metdus nem definilt rtket kap. Az utols Math metdus, amirl szt ejtnk, a random. A metdus egy kvzi-vletlen 0.0 s 1.0 kz es szmmal tr vissza. Pontosabban lerva: 0.0 Math.random() < 1.0 Hogy ms intervallumban kapjunk meg szmokat, mveleteket hajthatunk vgre a fggvny ltal visszaadott rtken. Pldul, ha egy egsz szmot szeretnnk kapni 1 s 10 kztt, akkor a kvetkezt kell begpelnnk:
int number = (int)(Math.random() * 10 + 1);
Megszorozva ezt az rtket 10-el a lehetsges rtkek intervalluma megvltozik: 0.0 szm < 10.0. 1-et hozzadva az intervallum ismt megvltozik: 1.0 szm < 11.0. Vgl, az rtk egssz konvertlsval egy konkrt szmot (int) kapunk 1 s 10 kztt. A Math.random hasznlata tkletes, ha egy egyszer szmot kell generlni. Ha egy vletlen szmsorozatot kell generlni, akkor egy hivatkozst kell ltrehozni a java.util.Randomra, s meghvni ennek az objektumnak a klnbz metdusait.
91. oldal
19, majd 20 19, majd 11 10, majd 1 fordtsi hiba miatt nem indul el
92. oldal
10.Tmbk
A tmb egy olyan vltoz, amely tbb azonos tpus adatot tartalmaz. A tmb (futsidei) hossza a ltrehozsakor kerl megllaptsra, s attl kezdve a tmb egy lland mret adatszerkezet.
A tmb egy eleme egyike a tmbben tallhat tagoknak, mely a tmbben elfoglalt helye (indexe) alapjn rhet el. Ha klnbz tpus adatokat akarunk trolni egy szerkezeten bell, vagy olyan szerkezetre van szksg, melynek mrete dinamikusan mdosthat, akkor hasznljunk a tmb helyett olyan gyjtemny implementcikat, mint az ArrayList. Fontos megjegyezni, hogy a tmbk objektumok, eltren a C nyelvtl. Ez sok mindenben befolysolja a mkdst.
A program kimenete:
0 1 2 3 4 5 6 7 8 9
Tmbk deklarlsa
Ez a sor egy pldaprogrambl val, s egy tmb tpus vltozt deklarl:
int[] anArray;
Mint minden msfajta vltoz deklarlsakor, a tmb deklarlsa is kt rszbl ll: a tmb tpusa s a tmb neve. A tmb tpusa a tmb[] formtumban rhat, ahol a tpus a tmb ltal tartalmazott elemek tpusa, a [] pedig azt jelzi, hogy tmbrl van sz. A tmb minden eleme azonos tpus! A fenti plda int[] tmbt hasznl, teht az anArray nev tmb int tpus egszek trolsra lesz alkalmas. Nhny ms tpust trolni kpes tmb ltrehozsa:
10.Tmbk
float[] anArrayOfFloats; boolean[] anArrayOfBooleans; Object[] anArrayOfObjects; String[] anArrayOfStrings;
93. oldal
gy is rhat a deklarci:
float anArrayOfFloats[];
Ez a forma nem ajnlott, mert a zrjelek jelzik, hogy tmbrl van sz, gy azok a tpussal tartoznak ssze, nem pedig a tmb nevvel. A tmb vltozk deklarlsval mint brmely ms nem primitv vltozval sem jn ltre tnyleges tmb, s nem foglal le helyet a memriban az elemek szmra. A pldakdban explicit mdon kell ltrehozni a tmbt s elnevezni anArray-nek.
Tmbk ltrehozsa
Tmb ltrehozhat explicit mdon a Java new opertora segtsgvel. A pldaprogram kvetkez rszben 10 egsz trolsra szolgl tmbhz elegend memrit foglalunk le, s elnevezzk a mr korbban deklarlt anArray-nek.
anArray = new int[10];
ltalban tmb ltrehozsakor hasznlni kell a new opertort, majd a tmb elemeinek tpust s vgl a tmb mrett kell megadni szgletes zrjelek kztt:
new elemtpus[tmbmret];
Ha a new opertort kihagytuk volna a pldaprogrambl, a fordt lellt volna kvetkez hibazenettel:
ArrayDemo.java:4: Variable anArray may not have been initialized.
Tmbelemek elrse
Most, hogy mr megtrtnt a memriafoglals a tmb szmra, a program rtkeket rendel a tmb elemeihez.
for (int i = 0; i < anArray.length; i++) { anArray[i] = i; System.out.print(anArray[i] + " "); }
A kd ezen rsze azt mutatja be, hogy ahhoz, hogy hivatkozni tudjuk a tmb brmely elemre bers vagy kiolvass cljbl, a tmb nevhez egy []-et kell rni. A zrjelben (vltoz vagy egyb kifejezs segtsgvel) rt rtk az elrni kvnt tmbelem indext jelli.
Megjegyzs: A tmb (mivel objektum), tudja, hogy mekkora a mrete, s milyen index hasznlhat az indexels sorn. rvnytelen index esetn (a C nyelvvel szemben) a hiba futs kzben egyrtelmen kiderl: a futtatkrnyezetet egy ArrayIndexOutOfBoundsExeption tpus kivtelt dob.
94. oldal
Figyelem! Azok, akiknek j a Java programnyelv, gyakran res zrjelet raknak a length utn. Ez nem mkdik, mert a length nem metdus! A length egy csak olvashat adattag, melyet a Java platform nyjt minden tmb szmra. A for ciklus a programunkban bejrja az anArray minden elemt, rtket adva nekik. A ciklus anArray.lengthet hasznl a ciklus vgnek megllaptshoz.
A program kimenete:
string one string two string three
A JDK 5.0s s ksbbi verzii esetn lehetsg van a tmb elemeinek bejrshoz egy jabb szintaktika alkalmazsra. Ezt ms nyelvekben hasznlt nevk alapjn for-each ciklusnak is szoks hvni. Figyelni kell azonban arra, hogy a ciklust ugyangy a for kulcssz vezeti be, mint a hagyomnyos for ciklust.
String[] anArray = {"String One","String Two","String Three"}; for (String s : anArray) { System.out.println(s.toLowerCase()); }
95. oldal
Ez egy potencilis hibzsi lehetsg, melyet az jdonslt Java programozk gyakran elkvetnek, amikor objektum tmbket hasznlnak. Miutn a fenti kdsor vgrehajtdik, a tmb ltrejtt s kpes 5 Integer objektum trolsra, br a tmbnek mg nincs eleme. res. A programnak explicit mdon ltre kell hoznia az objektumokat, s belerakni a tmbbe. Ez nyilvnvalnak tnik, habr sok kezd azt gondolja, fenti kdrszlet ltrehozza az res tmbt s mg 5 res objektumot is a tmbbe. Ha a tmbelemek ltrehozsa nlkl prblunk azokra hivatkozni, akkor a futtatkrnyezetet NullPointerException-t fog dobni. A problma elfordulsa mg veszlyesebb, ha a tmb ltrehozsa a konstruktorban, vagy ms kezdrtk lltssal trtnik, s mshol hasznljuk a programban.
} }
A program kimenetele:
Flintstones: Fred Wilma Pebbles Dino Rubbles: Barney Betty Bam Bam Jetsons: George Jane Elroy Judy Rosie Astro Scooby Doo Gang: Scooby Doo Shaggy Velma Fred Daphne
96. oldal
Vegyk szre, hogy mindegyik msodlagos tmb klnbz hosszsg. A mellktmbk nevei cartoons[0], cartoons[1], s gy tovbb. Mint az objektumok tmbjeinl, ltre kell hoznunk a msodlagos tmbket a tmbn bell. Ha nem hasznlunk kezdeti paramterinicializlst, akkor a kvetkezhz hasonl kdot kell rnunk:
public class ArrayOfArraysDemo2 { public static void main(String[] args) { int[][] aMatrix = new int[4][]; for (int i = 0; i < aMatrix.length; i++) { aMatrix[i] = new int[5]; for (int j = 0; j < aMatrix[i].length; j++) { aMatrix[i][j] = i + j; } } for (int i = 0; i < aMatrix.length; i++) { for (int j = 0; j < aMatrix[i].length; j++) { System.out.print(aMatrix[i][j] + " "); } System.out.println(); } } 0 1 2 3 1 2 3 4 }
A program kimenetele:
2 3 4 5 3 4 5 6 4 5 6 7
Meg kell adni a tmb hosszsgt, amikor ltrehozzuk. Teht egy tmbnek, ami tartalmaz msodlagos tmbket, meg kell adni a hosszsgt, amikor ltrehozzuk, de nem kell megadni a msodlagos tmbk hosszsgt is.
A kt Object paramter rmutat a kiindul s a cl tmbre. A hrom int paramter jelzi a kezd helyet a forrs s a cltmbn bell, s az elemek szmt, amennyit msolni akarunk. A kvetkez kp illusztrlja, hogyan megy vgbe a msols:
10.Tmbk
97. oldal
A kvetkez ArrayCopyDemo program hasznlja az arraycopy metdust, ami az elemeket a copyFrom tmbbl a copyTo tmbbe msolja.
public class ArrayCopyDemo { public static void main(String[] args) { char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'a', 't', 'e', 'd' }; char[] copyTo = new char[7]; System.arraycopy(copyFrom, 2, copyTo, 0, 7); System.out.println(new String(copyTo));
} }
A program kimenetele:
caffein
Az eredmnytmbt ltre kell hozni, mieltt meghvdik az arraycopy metdus, s elg nagymretnek kell lennie, hogy belefrjenek a msoland tmb elemei. Tmbkezelshez tovbbi szolgltatsokat nyjt a java.util.Arrays osztly is.
Melyik fordul le? String temp [] = new String {"j" "a" "z"}; String temp [] = { "j " " b" "c"}; String temp = {"a", "b", "c"}; String temp [] = {"a", "b", "c"};
Hogyan tudhatjuk meg a myarray tmb mrett? myarray.length(); myarray.length; myarray.size myarray.size();
rjon programot, amely gymlcsnevek tmbjt hozza ltre! Ezutn keresse meg s rja ki, melyik gymlcs nevben van a legtbb magnhangz. tlet: rdemes egy azonos mret msik tmbt ltrehozni, amiben a darabszmokat troljuk. rjon programot, amely a kvetkez tartalm mtrixot hozza ltre, majd ki is rja azt a kpernyre:
2 1 2 2 3 1 2 3 4 2 1 1 1 1 2 1
Ezutn transzponlja (a ftlra tkrzze) a mtrixot, s gy is rja ki. (Segtsgknt: a kvetkez eredmnyt kell a kpernyn kapni:)
2 3 4 1 1 1 2 1 2 2 1 2 2 3 1 1
Megjegyzs: Az idelis megolds a helyben tkrzs, de ha ez nem megy, lehet prblkozni azzal is, hogy a transzponlt egy msik tmbben jjjn ltre.
rjon programot, amely az 5x5-s egysgmtrixot hozza ltre! Az egysgmtrixban ftlbeli elemek 1-et, mg az ezen kvli elemek 0-t tartalmaznak.
99. oldal
A ftl elemei legyenek 2-esek, a ftl alatti elemek 1-esek, a ftl feletti elemek pedig ne szerepeljenek a mtrixban (tekinthetjk nullknak is). rja ki a kpernyre is ilyen formban.
100. oldal
A kvetkez Bicycle osztly pldjn bemutatjuk az osztly elemeit. Az osztly deklarci az osztly kdjnak az els sora. Minimlisan az osztly deklarci meghatrozza az osztly nevt. Az osztlytrzs az osztly deklarcit kveti, s kapcsos zrjelek kztt ll. Az osztly trzs tartalmazza mindazt a kdot, amely hozzjrul az osztlybl ltrehozott objektumok letciklushoz: konstruktorok, j objektumok inicializlsra, vltoz deklarcik, amelyek megadjk az osztly s objektumnak llapott, s eljrsokat az osztly s objektumai viselkedsnek meghatrozsra.
private int cadence; private int gear; private int speed;
Az osztly hrom tagvltozt definil az osztlytrzsn bell. A kvetkez konsrtruktor a tagvltozk kezdrtkeinek belltsra biztost lehetsget.
public Bicycle(int startCadence, int startSpeed, int startGear) { gear = startGear; cadence = startCadence; speed = startSpeed; }
11.Osztlyok ltrehozsa
class MyClass { // tagvltozk, konstruktor s metdus deklarcik }
101. oldal
A kd els sort osztlydeklarcinak nevezzk. A megelz osztlydeklarci egy minimlis osztlydeklarci; csak azokat az elemeket tartalmazza, amelyek felttlenl szksgesek. Nhny aspektusa ennek az osztlynak ugyan nincs specifiklva, alaprtelmezettek. A legfontosabb az, hogy a Myclass osztly kzvetlen sosztlya az Object osztly. Tbb informci is megadhat az osztlyrl, idertve az sosztlya nevt, azt, hogy implementl-e interfszt vagy nem, hogy lehetnek-e leszrmazott osztlyai s gy tovbb, mindezt az osztlydeklarcin bell. A kvetkez tblzat bemutatja az sszes lehetsges elemet, mely elfordulhat egy osztlydeklarciban elfordulsuk szksges sorrendjben. public abstract final class NameOfClass extends Super implement Interfaces { } osztlytrzs (opcionlis) az osztly nyilvnosan hozzfrhet (opcionlis) az osztlyt nem lehet pldnyostani (opcionlis) az osztly nem lehet se ms osztlynak az osztly neve (opcionlis) az osztly se (opcionlis) az osztly ltal implementlt interfszek az osztly mkdst biztostja
Ez a kd deklarlja a tagvltozkat, de ms vltozkat, mint pldul a loklis vltozkat nem. A tagvltozk deklarcija az osztlytrzsben, brmilyen konstruktoron s eljrson kvl trtnik meg. Az itt deklarlt tagvltozk int tpusak. Termszetesen a deklarcik komplexebbek is lehetnek. A private kulcssz mint privt tagokat vezeti be a tagokat. Ez azt jelenti, hogy csak a Bicycle osztly tagjai frhetnek hozzjuk. Nem csak tpust, nevet s hozzfrsi szintet lehet meghatrozni, hanem ms attribtumokat is, idertve azt, hogy a vltoz-e, vagy konstans. A kvetkez tblzat tartalmazza az sszes lehetsges tagvltoz deklarcis elemet.
A kvetkez ngy hozzfrsi szint szerint vezrelhet, hogy ms osztlyok hogyan frhessenek hozz a tagvltozkhoz: public, protected, csomag szint, vagy private. (opcionlis) Osztlyvltozt, s nem pldnyvltozt deklarl. (opcionlis) a vltoz rtke vgleges, meg nem vltoztathat (konstans) Fordtsi idej hibt okoz, ha a program megprbl megvltoztatni egy final vltozt. Szoks szerint a konstans rtkek nevei nagybetvel rdnak. A kvetkez vltoz deklarci a PI vltozt hatrozza meg, melynek rtke (.3.141592653589793), s nem lehet megvltoztatni: final double PI = 3.141592653589793;
static final
(opcionlis) a vltozt tmenetiknt azonostja (opcionlis) Megakadlyozza, hogy a fordt vgrehajtson bizonyos optimalizlsokat a tagon. A vltoz tpusa s neve Mint ms vltozknak, a tagvltozknak is szksges, hogy tpusa legyen. Hasznlhatk egyszer tpusnevek, mint pldul az int, float vagy boolean. Tovbb hasznlhatk referencia tpusok, mint pldul a tmb, objektum vagy interfsz nevek. Egy tagvltoz neve lehet minden megengedett azonost, mely szoks szerint kisbetvel kezddik. Kt vagy tbb tagvltoznak nem lehet megegyez neve egy osztlyon bell.
Mint az osztlyt, a metdust is kt nagyobb rsz hatroz meg: a metdus deklarcija s a metdus trzse. A metdus deklarci meghatrozza az sszes metdus tulajdonsgt gy, mint az elrsi szint, visszatr tpus, nv, s paramterek. A metdus trzs az a rsz, ahol minden mvelet helyet foglal. Olyan instrukcikat tartalmaz, amelyre a metdus vgrehajtshoz van szksg. A metdus deklarci ktelez elemei: a metdus neve, visszatr tpusa, s egy zrjelpr: (). A kvetkez tblzat megmutat minden lehetsges rszt a metdus deklarcijban.
11.Osztlyok ltrehozsa hozzfrsi szint static abstract final native synchronized returnType methodName ( paramList ) throws exceptions (opcionlis) A metdus hozzfrsi szintje (opcionlis) Osztly metdust deklarl (opcionlis) Jelzi, hogy a metdusnak nincs trzse
103. oldal
(opcionlis) Jelzi, hogy a metdus nem rhat fell a leszrmazottakban (opcionlis) Jelzi, hogy a metdust ms nyelven kszlt (opcionlis) A metdus kr egy monitort a szinkronizlt futshoz Az metdus visszatr tpusa s neve A paramterlista a metdushoz (opcionlis) A metdus le nem kezelt kivtelei
A metdus neve
A metdus neve szoks szerint kis betvel kezddik, hasonlan a vltozk neveihez. ltalban az osztlyon bell egyedi neve van a metdusnak. Ha a metdus neve, paramterlistja s visszatrsi rtke megegyezik az sben definilt metdussal, akkor fellrja azt. Javban az is megengedett, hogy ugyanazzal a nvvel, de klnbz paramterlistval hozzunk ltre metdusokat. Nzzk a kvetkez pldt:
public class DataArtist { ... public void draw(String s) { ... } public void draw(int i) { ... } public void draw(float f) { ... }
Azonos paramterlistval, de klnbz tpus visszatrsi rtkkel nem lehet metdusokat ltrehozni.
11.4. Konstruktorok
Minden osztlyban van legalbb egy konstruktor. A konstruktor inicializlja az j objektumot. A neve ugyanaz kell, hogy legyen, mint az osztly. Pldul a Bicycle nev egyszer osztlynak a konstruktora is Bicycle:
104. oldal
Ebben a pldban a konstruktor a paramter alapjn tudja ltrehozni a kvnt mret tmbt. A konstruktor nem metdus, gy nincs visszatr tpusa. A konstruktor a new opertor hatsra hvdik meg, majd visszaadja a ltrejtt objektumot. Egy msik konstruktor csupn a 0 kezdrtkeket lltja be:
public Bicycle() { gear = 0; cadence = 0; speed = 0; }
Mindkt konstruktornak ugyanaz a neve (Bicycle), de a paramterlistjuk klnbz. A metdusokhoz hasonlan a konstruktorokat is megklnbzteti a Java platform a paramterek szma s tpusa alapjn. Ezrt nem rhatunk kt ugyanolyan paramterlistval rendelkez konstruktort. (Klnben a fordt nem lenne kpes ket megklnbztetni, gy fordtsi hibt adna.) Amikor ltrehozunk egy osztlyt, meg kell adnunk, hogy az egyes pldnyok milyen konstruktorokkal legyen ltrehozhatk. A korbban bemutatott Rectangle osztly ngy konstruktort tartalmaz, s gy lehetv teszi a klnbz inicializlsi lehetsgek kzti vlasztst. Nem kell konstruktorokat rni az osztlyainkhoz, ha gy is el tudja ltni a feladatt. A rendszer automatikusan ltrehoz egy paramter nlkli konstruktort, klnben nem tudnnk pldnyt ltrehozni. A konstruktor deklarcijnl hasznlhatjuk a kvetkez hozzfrsi szinteket: private Csak ez az osztly hasznlhatja ezt a konstruktort. Ha minden konstruktorok privt, akkor az osztlyban lehet egy publikus osztly metdus, mely ltrehoz s inicializl egy pldnyt. protected Az osztly s leszrmazott osztlyai hasznlhatjk ezt a konstruktort. public Minden osztly hasznlhatja ezt a konstruktort. nincs megadva Csak az osztllyal azonos csomagban elhelyezked osztlyokbl lesz elrhet ez a konstruktor.
11.Osztlyok ltrehozsa
105. oldal
public double computePayment(double loanAmt, double rate, double futureValue, int numPeriods) { double I, partial1, denominator, answer; I = rate / 100.0; partial1 = Math.pow((1 + I), (0.0 - numPeriods)); denominator = (1 - partial1) / I; answer = ((-1 * loanAmt) / denominator) - ((futureValue * partial1) / denominator); return answer; }
Ebben a metdusnak ngy paramtere van: a klcsn sszege, kamata, vgsszege, fizets gyakorisga. Az els hrom dupla pontossg lebeg pontos szm, mg a negyedik egsz szm. Ahogy ennl a metdusnl is lthat, a metdus vagy konstruktor paramterlistja vltoz deklarcik vesszvel elvlasztott listja, ahol minden vltoz deklarci tpus-nv prokkal van megadva. Amint lthatjuk a computePayment metdus trzsben a paramternevekkel egyszeren hivatkozunk az rtkkre.
Paramterek tpusa
A metdusok vagy konstruktorok paramterei tpussal rendelkeznek. A tpus lehet primitv (int, float, stb.), amint lthattuk a computePayment metdusnl, vagy referencia tpus (osztlyok, tmbk esetn). A kvetkez metdus egy tmbt lap paramterknt, majd ltrehoz egy j Polygon objektumot, s inicializlja a Point objektumok tmbjbl. (Felttelezzk, hogy a Point egy osztly, amelyik x, y koordintkat tartalmaz.)
public static Polygon polygonFrom (Point[] listOfPoints) { ... }
A Java nyelv nem engedi, hogy metdust egy msik metduson bell helyezznk el.
Paramter nevek
Amikor metdusban vagy konstruktorban paramtert deklarlunk, eldnthetjk, hogy milyen nevet adunk a paramternek. Ezt a nevet hasznlhatjuk a metdus trzsben a paramter rtkek elrsre. A paramter nevnek egyedinek kell lennie a hatskrn bell. Vagyis nem lehet ugyanaz, mint egy msik paramter, vagy loklis vltoz vagy brmely paramter neve egy catch zradkban ugyanazon a metduson vagy konstruktoron bell. Lehet viszont ugyanaz a nv, mint az osztly egy tagvltozja. Ebben az esetben, azt mondjuk, hogy a paramter elfedi a tagvltozt. Ilyen elfedett tagvltozt is el lehet rni, br kicsit krlmnyes. Pldul nzzk meg a kvetkez Circle osztlyt s a setOrigin metdust:
public class Circle { private int x, y, radius; public void setOrigin(int x, int y) { ... } }
A Circle osztlynak hrom tagvltozja van: x, y s radius. A setOrigin metdus kt paramtert vr, mindkettnek ugyanaz a neve, mint a tagvltoznak. A metdus mindkt paramtere elrejti az azonos nev tagvltozt. Ha a metdus trzsben hasznljuk az x
106. oldal
vagy y nevet, akkor a paramterekre s nem a tagvltozkra hivatkozunk. A tagvltoz elrshez minstett nevet kell hasznlni, amirl ksbb olvashat.
Ez gy nem mkdik. A red, green s blue vltoz ltezik ugyan, de a hatskre a getRGBColor metduson bell van. Amikor a metdusbl visszatr a program, ezek a vltozk megsznnek. rjuk jra a getRGBColor metdust, hogy az trtnjen, amit szerettnk volna. Elszr is, kell egy j RGBColor tpus, hogy megrizze a red, green s blue sznek rtkt:
public class RGBColor { public int red, green, blue; }
Most mr trhatjuk a getRGBColor metdust, hogy paramterknt RGBColor objektumot vrjon. A getRGBColor metdus visszatr az aktulis toll sznvel a belltott red, green s blue tagvltoz rtkvel az RGBColor paramter segtsgvel:
public class Pen { private int redValue, greenValue, blueValue; ... public void getRGBColor(RGBColor aColor) { aColor.red = redValue; aColor.green = greenValue; aColor.blue = blueValue; } }
Az gy visszaadott RBColor objektum a getRGBColor metduson kvl is megtartja rtkt, mivel az aColor egy objektumra hivatkozik, amely a metdus hatskrn kvl ltezik.
Megjegyzs: Termszetesen az is egy bizonyos rtelemben egyszerbb megolds lehetett volna, hogy a hrom rtk lekrdezshez hrom lekrdez metdust ksztnk. gy nem lett volna szksg egy j tpus bevezetsre. E megolds a kvetkez pont elolvassa utn el is kszthet.
11.Osztlyok ltrehozsa
107. oldal
A visszaadott rtk adattpusa meg kell, hogy egyezzen a metdus deklarlt visszatrsi rtkvel; ezrt nem lehetsges egsz szmot visszaadni olyan metdusbl, aminek logikai a visszatrsi rtktpusa. A fenti isEmpty metdus deklarlt visszatrsi rtk tpusa logikai (boolean), s a metdus megvalstsa szerint igaz (true), vagy hamis (false) logikai rtk kerl visszaadsra a teszt eredmnynek megfelelen.
Megjegyzs: A fenti kd helyett ltalban tmrebb rsmdot szoks alkalmazni. Ennek ellenre ebben a jegyzetben a jobb rthetsg kedvrt idnknt a hosszabb formt alkalmazzuk. A kvetkez kd az elzvel teljesen ekvivalens:
Az isEmpty metdus elemi (vagy primitv) tpust ad vissza. Egy metdus referencia adattpust is visszaadhat. Pldul ha a Stack osztly definilja a pop metdust, amely az Object referencia adattpust adja vissza:
public Object pop() { if (top == 0) { throw new EmptyStackException(); } Object obj = items[--top]; items[top] = null; return obj; }
Amikor egy metdus visszatrsi tpusa egy osztly, (mint ahogy a fenti pop esetn), a visszaadott objektum tpusa meg kell, hogy egyezzen a visszatrsi tpussal, vagy leszrmazottja kell, hogy legyen annak. Tegyk fel, hogy van egy olyan osztlyhierarchia, amelyben ImaginaryNumber a java.lang.Number leszrmazott osztlya, ami viszont az Object leszrmazott osztlya. Ezt mutatja az albbi bra:
108. oldal
Ezek utn tegyk fel, hogy egy metdus gy kerl deklarlsra, hogy egy Number-t ad vissza:
public Number returnANumber() { ... }
A returnANumber metdus visszaadhat egy ImaginaryNumber tpust, de nem adhat vissza Object tpust. ImaginaryNumber egy Number, mivel a Number leszrmazott osztlya. Ugyanakkor az Object nem felttlenl Number is egyben, lehet akr String, vagy akr egsz ms tpus is. Interfsz neveket is lehet visszatrsi tpusknt hasznlni. Ebben az esetben a visszaadott objektumnak a megadott interfszt (vagy leszrmazottjt) kell implementlnia.
A konstruktoron bell a this kulcssz hasznlhat arra is, hogy egy ugyanabba az osztlyba tartoz msik konstruktort meghvjunk. Ezt a metdust explicit konstruktor hvsnak nevezzk. Az albbi Rectangle osztly msknt kerl implementlsra, mint korbbi megolds.
public class Rectangle { private int x, y; private int width, height; public Rectangle() { this(0, 0, 0, 0); } public Rectangle(int width, int height) { this(0, 0, width, height); }
11.Osztlyok ltrehozsa
109. oldal
public Rectangle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } ...
Ez az osztly konstruktorok halmazt tartalmazza. Mindegyik konstruktor inicializlja a ngyszg (Rectangle) tagvltozinak egy rszt, vagy az sszeset. A konstruktorok konstans kezdrtket adnak minden olyan tagvltoznak, amelynek nem ad rtket valamelyik paramter. Pldul a paramter nlkli konstruktor a ngy paramteres konstruktort hvja, s nullkat ad kezdrtkeknek. Ahogy az eddigiekben is, a fordtprogram a paramterek szma s tpusa alapjn hatrozza meg, hogy melyik konstruktort kell meghvni. Amennyiben hasznljuk, gy az explicit konstruktorhvs a konstruktor els utastsa kell, hogy legyen.
Az els oszlop azt mutatja, hogy maga az osztly elrheti-e az adott jelzvel megjellt tagokat. Ahogy az lthat, az osztly mindig elrheti sajt tagjait. A msodik oszlop azt mutatja, hogy az eredeti osztllyal azonos csomagban lv ms osztlyok fggetlenl a szli kapcsolatoktl elrhetik-e a tagokat. Egy csomagban lv csoportok osztlyokkal s interfszekkel llnak kapcsolatban, tovbb elrsi vdelmet s trterlet felgyeletet biztostanak. (A csomagokrl egy ksbbi fejezetben lesz sz.) A harmadik oszlop azt jelzi, hogy az osztly leszrmazottai elrhetik-e a tagokat fggetlenl attl, hogy melyik csomagban vannak. A negyedik oszlop pedig azt jelzi, hogy az sszes osztly elrheti-e a tagokat. Az elrsi szintek kt mdon hatnak. Az els md az, amikor kls forrsbl szrmaz osztlyokat (pldul a Java platform osztlyait) hasznljuk, ekkor az elrsi szintek meghatrozzk, hogy ezen osztlyok melyik tagjait tudjuk elrni. A msik md az, hogy
110. oldal
amennyiben sajt osztlyokat runk, meghatrozhatjuk az elrsi szintet minden tagvltozhoz, metdushoz, illetve konstruktorhoz, amelyek az osztlyban szerepelnek. Tekintsk az osztlyok egy halmazt, s nzzk, hogyan mkdnek az elrsi szintek. A kvetkez bra az albbi pldban szerepl ngy osztlyt s a kzttk fennll kapcsolatokat mutatja:
11.Osztlyok ltrehozsa
111. oldal
Ahogy az lthat, az Alpha gy hivatkozik valamennyi tagvltozjra s valamennyi metdusra, ahogy az az elz tblzat osztly oszlopban szerepelt. A program kimenete a kvetkez lesz:
iamprivate Method iampackage Method iamprotected Method iampublic Method iamprivate: 1 iampackage: 2 iamprotected: 3 iampublic: 4
Egy tag elrsi szintje azt hatrozza meg, hogy melyik osztlyok rhetik el az illet tagot, s nem azt, hogy melyik pldnyok rhetik el. Pldul egy osztly valamennyi pldnya elrheti egy msik publikus tagjait. Az Alpha osztlyhoz hozzvehetnk egy pldny metdust, ami sszehasonltja az aktulis Alpha objektumot (this) egy msik objektummal az iamprivate vltozi alapjn:
package One; public class Alpha { ... public boolean isEqualTo(Alpha anotherAlpha) { if (this.iamprivate == anotherAlpha.iamprivate) { //megengedett return true; } else { return false; } }
112. oldal
A DeltaOne nem hivatkozhat az iamprivate vltozra, s nem hvhatja meg a privateMethod metdust, ugyanakkor elrheti az Alpha tbbi tagjt. Amennyiben a kommentezett sorok ell eltvoltjuk a // jellst, s gy prbljuk meg lefordtani az osztlyt, gy a fordtprogram hibt fog jelezni. A megjegyzsekkel futtatva a kvetkez eredmnyt kapjuk:
iampackage Method iamprotected Method iampublic Method iampackage: 2 iamprotected: 3 iampublic: 4
//System.out.println("iamprivate: " // + a.iamprivate); // nem megengedett //System.out.println("iampackage: " // + a.iampackage); // nem megengedett //System.out.println("iamprotected: " // + a.iamprotected); // nem megengedett System.out.println("iampublic " + a.iampublic); // megengedett AlphaTwo a2 = new AlphaTwo(); a2.protectedMethod(); // megengedett System.out.println("iamprotected: " + a2.iamprotected); // megengedett } }
Vegyk szre, hogy AlphaTwo nem hvhatja a protectedMethod metdust, s nem rheti el az iamprotected tagot az Alpha pldnyban (ez az sosztly), de hvhatja a protected-
11.Osztlyok ltrehozsa
113. oldal
Method metdust s elrheti az iamprotected-et az AlphaTwo pldnyban (vagy AlphaTwo leszrmazott osztly pldnyban). Ms szval a protected elrsi szint csak azt teszi lehetv egy leszrmazott osztly szmra, hogy egy vdett (protected) tagot csak akkor tudjon elrni, ha az illet tag hivatkozsa ugyanolyan tpus osztlyban, vagy leszrmazott osztlyban van. Az AlphaTwo futsnak eredmnye a kvetkez lesz:
iampublic Method iampublic: 4 iamprotected Method iamprotected: 3
} }
//System.out.println("iamprivate: " // + a.iamprivate); // nem megengedett //System.out.println("iampackage: " // + a.iampackage); // nem megengedett //System.out.println("iamprotected: " // + a.iamprotected); // nem megengedett System.out.println("iampublic: " + a.iampublic); // megengedett
Ha ms programozk is hasznlnak egy ksz osztlyt, szksges lehet annak biztostsa, hogy a tves hasznlat ne vezessen hibkhoz. Az elrsi szintek segthetnek ebben. A kvetkez javaslatok segtenek annak meghatrozsban, hogy egy adott taghoz melyik elrsi szint a legmegfelelbb. Hasznljuk a leginkbb korltoz, mg szszer elrsi szintet az egyes tagokra. Hacsak valami klnsen nem mond ellene, hasznljuk a private szintet. Kerljk a publikus tagvltozkat, kivve a konstansok estben. A publikus tagvltozk hasznlata oda vezethet, hogy valamelyik specilis implementcihoz fog kapcsoldni a program, s ez hibkat, tvedseket fog eredmnyezni. Tovbb, ha egy tagvltozt csak a hv metdus tud megvltoztatni, akkor ezt a vltozst jelezni lehet a tbbi osztly vagy objektum fel. Ugyanakkor a vltozs jelzse lehetetlen, ha
114. oldal
egy tagvltoz publikus elrs. A publikus elrs biztostsa ugyanakkor teljestmny nyeresget eredmnyezhet.
Megjegyzs: Ebben az oktatsi anyagban sok plda hasznl publikus tagvltozkat. A pldk s elvi kdrszletek nem szksgszeren felelnek meg azoknak a szigor tervezsi szablyoknak, amik egy API szmra elrsok.
Korltozzuk a vdett (protected) s a csomag (package) elrs tagvltozk szmt. Ha egy tagvltoz JavaBeans tulajdonsg, akkor az ktelezen private elrs.
11.Osztlyok ltrehozsa
115. oldal
Ha nincs egyb meghatrozs, akkor egy osztlyon bell deklarlt tag pldny tag lesz. gy az instanceInteger s az instanceMethod mindketten pldny tagok. A futtat rendszer a program sszes pldnyvltozjbl objektumonknt kszt egy pldnyt. gy az anInstance s az anotherInstance objektumok tartalmaznak egy-egy instanceInteger tagvltozt. Hozz tudunk frni a pldnyokhoz s meghvhatunk egy pldnymetdust egy hivatkozson keresztl. Ha az illegal felirattal megjellt sorok elejrl kitrljk a //-t, s megprbljuk lefordtani a programot, akkor egy hibazenetet kapunk. Egy osztlytag a static mdostval kerl deklarlsra. A main metduson kvl az AClass deklarl egy osztlyvltozt s egy osztlymetdust, melyeket classInteger-nek s classMethod-nak hvnak. A futtat rendszer osztlyonknt lefoglal egy osztlyvltozt, fggetlenl az osztly ltal lefoglalt pldnyok szmtl. A rendszer lefoglalja a memrit az osztlyvltoznak, legksbb akkor, amikor az elszr felhasznlsra kerl. Az osztly minden pldnyban elrhetek az osztly osztlyvltozi. Hozzfrhetnk az osztlyvltozhoz a pldnyokon keresztl, valamint az osztlyon keresztl is. Hasonlkppen egy osztly metdus is elrhet az osztlyban vagy egy pldnyon keresztl. Megjegyezzk, hogyha a program megvltoztatja a classVariable rtkt, akkor az megvltozik az sszes osztlypldnyban is.
11.9.1
Ez jl mkdik egyszer adattpusok esetben. Akkor is mkdik, ha tmbket vagy osztlyokat ksztnk. De vannak korltai is: Az inicializls csak kifejezst tartalmazhat, nem lehet pl. egy if-else utasts. Az inicializl kifejezs nem hvhat olyan fggvnyt, amely futsidej kivtelt dobhat. Ha olyan fggvnyt hv, amely futsidej kivtelt dob, mint pl. a NullPointerException, nem tudjuk a kivtelt elkapni.
Ha ezek a korltok gtolnak abban, hogy tagvltozt inicializljunk a deklarciban, az inicializl kd mshov is elhelyezhet. Egy osztlyvltoz inicializlshoz tegyk a kdot a statikus inicializl blokkba, ahogy a kvetkez plda mutatja. Egy pldny inicializlshoz tegyk a kdot a konstruktorba.
116. oldal
class Errors { static ResourceBundle errorStrings; static { try { errorStrings = ResourceBundle.getBundle("ErrorStrings"); } catch (java.util.MissingResourceException e) { //error recovery code here } } }
A statikus inicializl blokk a static kulcsszval kezddik, s mint ltalban, itt is kapcsos zrjelek kz tesszk a kdot. Az errorStrings a statikus inicializl blokkban kerl inicializlsra, mert a getBundle metdus dobhat kivtelt. Egy osztly tartalmazhat brmennyi statikus inicializl blokkot, amelyek brhol lehetnek az osztly trzsben. A futtatrendszer garantlja, hogy a forrskdban elfoglalt helyk sorrendjben kerlnek meghvsra az inicializl blokkok, mg mieltt a legels alkalommal hasznln az gy inicializlt osztlyvltozkat a program.
Pldnyvltozk inicializlsa
Pldnyvltozk inicializlsa az osztly konstruktorban is trtnhet. Ha az elz pldban szerepl errorStrings pldnyvltoz lenne, akkor az inicializl kdot az osztly konstruktorba tehetjk, az albbi plda szerint:
import java.util.ResourceBundle; class Errors { ResourceBundle errorStrings; Errors() { try { errorStrings = ResourceBundle.getBundle("ErrorStrings"); } catch (java.util.MissingResourceException e) { //error recovery code here } } }
11.10.Ellenrz krdsek
Mi az informcielrejts elnye, s hogyan valsul meg Javban? Mi az zenet? Hogyan valsul meg Javban? Mi az osztly? Hogyan hozzuk ltre Javban? Mi az objektum? Hogyan hozunk ltre Javban? Mi a metdus alrsa (szignatrja)? Mi a void tpus? Mik jtszdnak le egy metdus hvskor? Hogyan adja vissza a metdus a visszatrsi rtkt? Mi trtnik a metdus ltal deklarlt vltozkkal?
11.Osztlyok ltrehozsa Mi az objektum, mi az osztly s mi a kapcsolatuk? Mi a klnbsg a pldnyvltoz s az osztlyvltoz kztt? Mi az objektumreferencia? Mit jelent a null?
117. oldal
Hogyan hvhatjuk meg egy objektum metdusait az objektumreferencin keresztl? Mi a konstruktor? Hogyan hvjuk meg a konstruktort? Mi az alaprtelmezett konstruktor? Mikor generl alaprtelmezett konstruktort a fordt maga? Hogyan hivatkozhatunk egy objektum pldnyvltozira az objektumreferencin keresztl? Mit jelent az, hogy a Jva rendszerben egy szemtgyjt mkdik? Mik ennek a kvetkezmnyei? Mi a statikus vltoz? Elrhet-e a statikus vltoz nem statikus metdusbl? Milyen referencival lehet elrni a statikus vltozt? Mi a statikus metdus? Elrhet-e pldnyvltozt statikus metdus?
118. oldal
Az osztlyinicializl blokk belltja az objektum kezdeti rtkeit. Az inicializlk kzl elszr futnak le az osztlyinicializlk, s csak azutn kerlnek vgrehajtsra a pldnyinicializlk. Egy objektum ltrehozhat sajt osztlybl de csak osztlymetdusbl.
public void Test() {} public Test() {} public static Test() {} public static void Test() {}
11.11.Gyakorl feladatok
Ksztsen Brtn osztlyt, amely a trk szultn brtne ajtajainak nyitott llapott kpes trolni! A konstruktor paramterknt a brtn mrett kapja meg (pl. 100). Hozzon ltre egy ekkora mret alkalmas tmbt, s gondoskodjon a megfelel kezdrtkrl (az ajtk kezdetben zrva vannak). A kulcsFordt metdus paramterknt kapja, hogy hnyas szm cella kulcst kell tfordtani (ha nyitva volt, akkor bezrja, s fordtva). Nem megfelel index esetn magyar nyelv zenetet tartalmaz kivtelt dobjon (nem itt kell a hibazenetet a kpernyre rni). Oldja meg, hogy nyitott cellk szma jelenjen meg a konzolon, ha a System.out.println paramtereknt egy Brtn objektumot adunk meg (teht rja fell az rkltt toString metdust). Ksztsen main metdust, amely az eredeti jtkos feladat szerint elszr minden cella, majd minden msodik, minden harmadik stb., vgl a szzadik cella kulcst fordtja t, majd kirja a szabadul foglyok szmt. Ksztsen Anagramma osztlyt, amely sztringek betinek keversre hasznlhat. A statikus fordt metdus paramterknt kapjon egy String-et, visszaad egy msik String objektumot, amely az eredeti szveg els s utols betjt megcserlve tartalmazza (a tbbi vltozatlan).
11.Osztlyok ltrehozsa
119. oldal
A szintn statikus kever metdus tnyleges keverst hajtson vgre a vletlenszm-genertor (lsd java.util.Random.nextInt() metdus) segtsgvel. (Tipp: pl. 50-szer generljunk kt vletlen indexet, s cserljk meg a kt indexnl lev karaktert. Mg jobb, ha nem fix, hanem a String hossztl fgg ismtlst hajt vgre.) A main metdus olvasson be a billentyzetrl szavakat, s rja ki azok fordt s kever metdussal kapott mdostsait.
120. oldal
12.rklds
A java.lang csomagban definilt Object osztly meghatrozza s megvalstja azokat a metdusokat, amelyek minden osztly szmra szksgesek. A kvetkez brn lthat, hogy sok osztly ered az Object-bl, majd sok tovbbi osztly szrmazik az elbbi osztlyokbl, s gy tovbb, ltrehozva ezzel az osztlyok hierarchijt.
A hierarchia cscsn ll Object az osztlyok legltalnosabbja. A hierarchia aljn tallhat osztlyok sokkal specializltabb viselkedst eredmnyeznek. Egy leszrmazott osztly valamely osztlybl szrmazik. A superclass kifejezs (tovbbiakban szlosztly vagy sosztly) egy osztly kzvetlen sre/eldjre, vagy annak brmely felmen osztlyra utal. Minden osztlynak csak s kizrlag egyetlen kzvetlen szlosztlya van. Egy leszrmazott osztly a vltozit s metdusait a szlosztlytl rkli. A leszrmazott osztly szmra azonban lehet, hogy nem elrhet egy rkltt vltoz vagy fggvny. Pldul, egy leszrmazott osztly szmra nem rhet el egy private tag, ami a felsbb osztlytl rkldtt. Mondhatnnk persze, hogy akkor az a tag egyltaln nem is rkldtt. De igenis rkldtt. Akkor vlik ez fontoss, amikor egy olyan bels osztlyt hasznlunk, aminek van hozzfrse a mellkelt osztlyok private tagjaihoz. Ne feledjk, hogy a konstruktorok nem metdusok, teht az leszrmazott osztlyok nem rklhetik azokat.
12.rklds
121. oldal
A fellr metdusnak neve, valamint paramtereinek szma s tpusa, valamint viszszatrsi rtke megegyezik azzal a metdussal, amelyet fellr. (Valjban a leszrmazott osztlybeli metdus visszatrsi tpusa lehet a szlosztly visszatr tpusnak leszrmazottja is a Java 5 ta.) A fellr metdusnak lehet az stl eltr throws zradka, ha nem ad meg olyan tpusokat, melyek nincsenek a fellrt metdus zradkban elrva. Msrszt, a fellr metdus lthatsga lehet bvebb, mint a fellrt metdus, de szkebb nem. Pldul a szl osztly protected metdusa a leszrmazott osztlyban publikuss (public) tehet, de privtt (private) nem.
Megjegyzs: rdemes tgondolni e szablyok httert. Egy leszrmazott osztly objektuma brhol hasznlhat, ahol egy sosztlybeli objektum is. ppen ezrt a leszrmazott semelyik tagjnak lthatsga nem szklhet, hiszen akkor az ilyen hasznlat lehetetlen lenne. Ugyangy egy fellrt metdus ltal dobott jfajta kivtel kezelse nem lenne biztostott.
Egy leszrmazott osztly nem tudja fellrni az olyan metdusokat, melyek az sosztlyban vgleges (final) minsts (a definci szerint a vgleges metdusok nem fellrhatk). Ha mgis megprblunk fellrni egy vgleges metdust, a fordt hibazenetet kld. Egy leszrmazott osztlynak fell kell rnia azon metdusokat, melyek a felsbb osztlyban absztraktnak (abstract) nyilvntottak, vagy maga a leszrmazott osztly is absztrakt kell, hogy legyen. Emlkezznk vissza, hogy a Java programnyelv megengedi a metdusok tlterhelst, ha a metdus paramtereinek a szmt vagy tpust megvltoztatjuk. Egy sosztlyban is megengedhet a metdusok tlterhelse. Albbiakban nzznk egy pldt a toString metdus tlterhelsre:
public class MyClass { private int anInt = 4; public String toString() { return "Instance of MyClass. anInt = " + anInt; } public String toString(String prefix) { return prefix + ": " + toString(); }
Amint azt a plda illusztrlja, tlterhelhetnk egy sosztlybeli metdust, hogy tovbbi funkcikkal is szolglhasson. Amikor egy olyan metdus runk, mely azonos nev a felsbb osztlybeli metdussal, le kell ellenrizni a paramtereket s a kivtellistt (throws zradk), hogy biztosak lehessnk afell, hogy a fellrs olyan lett, amilyennek akartuk. Ha egy leszrmazott osztly egy osztlymetdust ugyanazzal az alrssal definil, mint a felsbb osztlybeli metdus, akkor a leszrmazott osztly metdusa elrejti (msknt fogalmazva elfedi) a szlosztlybelit. Nagy jelentsge van az elrejts s a fellrs megklnbztetsnek. Nzzk meg egy pldn keresztl, hogy mirt! E plda kt osztlyt tartalmaz. Az els az Animal, melyben van egy pldnymetdus s egy osztlymetdus:
public class Animal { public static void hide() { System.out.println("The hide method in Animal."); } public void override() { System.out.println("The override method in Animal."); } }
122. oldal
A Cat osztly fellrja az override metdust az Animal-ban, s elrejti a hide osztlymetdust az Animal-ban. Ebben az osztlyban a main metdus ltrehoz egy Cat pldnyt, beteszi az Animal tpus hivatkozs al is, majd elhvja mind az elrejtett, mind a fellrt metdust. A program eredmnye a kvetkez:
The hide method in Animal. The override method in Cat.
A szlosztlybl hvjuk meg a rejtett metdust, a leszrmazott osztlybl pedig a fellrtat. Osztlymetdushoz a futtatrendszer azt a metdust hvja meg, mely a hivatkozs szerkesztsi idej tpusban van definilva, amellyel a metdust elneveztk. A pldnkban az myAnimal szerkesztsi idej tpusa az Animal. Ekkppen a futtatrendszer az Animal-ban definilt rejtett metdust hvja meg. A pldnymetdusnl a futtatrendszer a hivatkozs futsidej tpusban meghatrozott metdust hvja meg. A pldban az myAnimal futsidej tpusa a Cat. Ekkppen a futtatrendszer a Cat-ban definilt fellr metdust hvja meg. Egy pldnymetdus nem tud fellrni egy osztlymetdust, s egy osztlymetdus nem tud elrejteni egy pldnymetdust. Mindkt esetben fordtsi hibt kapunk.
12.rklds
public void aMethod() { aVariable = true; }
123. oldal
Most kvetkezzen a Subclass nev leszrmazott osztly, mely fellrja aMethod-ot s aVariable-t:
public class Subclass extends Superclass { public boolean aVariable; //hides aVariable in Superclass public void aMethod() { //overrides aMethod in Superclass aVariable = false; super.aMethod(); System.out.println(aVariable); System.out.println(super.aVariable); } }
A leszrmazott osztlyon bell az aVariable nv a SubClass-ban deklarltra utalt, amely a szlosztlyban deklarltat elrejti. Hasonlkppen, az aMethod nv a SubClass-ban deklarltra utalt, amely felsbb osztlyban deklarltat fellrja. Teht ha egy a szlosztlybl rklt aVariable-ra s aMethod-ra szeretnnk utalni, a leszrmazott osztlynak egy minstett nevet kell hasznlnia, hasznlva a super-t, mint azt lttuk. A Subclass aMethod metdusa a kvetkezket rja ki:
false true
Hasznlhatjuk a super-t a konstruktoron bell is az sosztly konstruktora meghvsra. A kvetkez kdplda bemutatja a Thread osztly egy rszt az osztly lnyegben tbbszl programfutst tesz lehetv , amely vgrehajt egy animcit. Az AnimationThread osztly konstruktora bellt nhny kezdeti rtkeket, ilyenek pldul a keretsebessg s a kpek szma, majd a vgn letlti a kpeket:
class AnimationThread extends Thread { int framesPerSecond; int numImages; Image[] images; AnimationThread(int fps, int num) { super("AnimationThread"); this.framesPerSecond = fps; this.numImages = num; this.images = new Image[numImages]; for (int i = 0; i <= numImages; i++) { ... // Load all the images. ... } } ... }
A flkvrrel szedett sor a kzvetlen szlosztly konstruktornak explicit meghvsa, melyet a Thread nyjt. Ez a Thread konstruktor tvesz egy String-et, s gy nevezi a Thread-et. Ha a leszrmazott osztly konstruktorban van explicit super konstruktorhvs, akkor annak az elsnek kell lennie. Ha egy konstruktor nem hv meg explicit mdon egy szlosztlybeli konstruktort, akkor a Java futtatrendszer automatikusan (implicit)
124. oldal
a szlosztly paramter nlkli konstruktort hvja meg, mg mieltt a konstruktoron bell brmi utastst vgrehajtana.
Megjegyzs: ha a szl osztlyban nem ll rendelkezsre paramter nlkli konstruktor, akkor fordtsi hibt kapunk. Ilyen esetben ktelesek vagyunk explicit paramteres konstruktorhvst alkalmazni.
A clone metdus
A clone metdust akkor hasznljuk, ha ltre szeretnnk hozni egy objektumot, egy mr meglv objektumbl (msolatot kszteni rla). Az adott osztllyal megegyez tpus j pldnyt hoz ltre:
aCloneableObject.clone();
A metdus a CloneNotSupportedException kivtelt dobja, ha a klnozs nem tmogatott az osztly szmra. A klnozs akkor tmogatott, ha az osztly implementlja a Cloneable interfszt. Habr az Object tartalmazza a Clone metdust, nincsen megvalstva az interfsz. Ha az objektum, ahol a clone-ra hivatkoztunk, nem implementlja a cloneable interfszt, egy eredetivel azonos tpus s rtk objektum jn ltre. Legegyszerbb azonban, ha az osztly deklarciban ltrehozunk egy implements Cloneable sort. Bizonyos osztlyoknl a helyes mkds felttele a clone felldefinilsa. Tekintsnk egy Stack osztlyt, mely tartalmaz egy tagvltozt, mely az Object-ek tmbjre hivatkozik. Ha a Stack az Object osztly clone metdusra pl, akkor az eredeti s a msolt Stack ugyanazokat az elemeket fogja tartalmazni, mivel az adattag tmb, s msolskor csak referencia msols fog trtnni. A Stack osztlynak olyan clone implementcira van szksge, amely lemsolja a Stack objektum adattagjait, ezzel biztostva a megfelel tartalom sztvlasztst:
public class Stack implements Cloneable { private Object[] items; private int top; ...
12.rklds
125. oldal
protected Stack clone() { try { Stack s = (Stack)super.clone(); //clone the stack s.items = (Object)items.clone(); //clone the array return s; // return the clone } catch (CloneNotSupportedException e) { //This shouldn't happen because Stack is Cloneable. throw new InternalError(); } } }
Az implementci viszonylag egyszer. Elszr a clone metdus Object implementcija hvdik meg a super.clone segtsgvel, mely ltrehoz s inicializl egy Stack objektumot. Ilyenkor mindkt objektum ugyanazokat az objektumokat tartalmazza. Ezutn a metdus lemsolja az objektumokat, s a metdus Stack-el tr vissza.
Megjegyzs: A clone metdus nem a new-t hasznlja a msolat ltrehozsnl s nem hv konstruktorokat, helyette a super.clone-t hasznlja, mely ltrehozza az objektumot a megfelel tpussal, s engedlyezi a msolst, minek eredmnyekppen a kvnt msolatot kapjuk. rdemes mg azt is megfigyelni, hogy az adattag msolst sem kzzel vgezte a metdus, hanem a tmb objektum clone metdusval. Ez a metdus egy msik azonos mret tmbt hoz ltre, aminek elemeirl is msolat kszl. (A tmbben trolt tagokrl mr nem fog msolat kszlni, de ez nem is clja egy verem msolsnak.)
A program kimenete:
objects are equal
Egyenlk, mivel az rtkk megegyezik. Ha kt objektum egyenl az equals metdus szerint, akkor a hashCode metdus ltal szolgltatott rtkeknek is meg kell egyeznik. (Figyelem, fordtva ez nem felttlenl igaz!) Ha az equals mkdse nem megfelel az osztlyunk szmra, akkor fell kell rnunk az osztlyunkban. A hashCode metdus lltja el az objektumok hash kdjt, ami pldul akkor lehet szksges, ha az objektumot hashtblban troljuk. Hash kdknt (a metdus visszatrsi rtkeknt) mindig egy int tpus szmot kapunk. Helyes hash fggvny rsa egyszer, azonban hatkony fggvny rsa nehz lehet, komolyabb munkt ignyel. Ez a tma azonban mr nem fr bele a jegyzetnkbe.
126. oldal
A finalize metdus
Az Object osztly ugyancsak tartalmazza a finalize metdust. A szemtgyjt meghvja, ha mr nincs egyetlen hivatkozs sem az objektumra. A finalize metdus automatikusan meghvdik, melyet a legtbb osztly hasznl, ezrt nem is kell kln meghvni. A finalize metdussal legtbbszr nem kell trdnnk, az stl rklt metdus tbbnyire megfelelen mkdik.
A toString metdus
Az objektumot String-knt brzolja. Hasznos minden j osztly defincija sorn fellrni, hogy a megfelel rtkeket reprezentlhassa. Hasznlhatjuk a toString-et a System.out.println-nel egytt az objektumok szveges megjelentsre, pl.:
System.out.println(new Double(Math.PI).toString());
A futs eredmnye:
3,14159
Nagyon hasznos ez a metdus akkor, ha a program tesztelsi fzisban bizonyos objektumok tartalmt ellenrizni szeretnnk. Ilyenkor csak ki kell rni a krdses objektumot, pldul a konzolra:
System.out.println(anObject);
A getClass metdus
Visszaadja a futsidej osztlyt az objektumnak. Az Object osztly nem engedi meg a getClass metdus felldefinilst (final). A kvetkez metdus az objektum osztlynevt jelenti meg:
void PrintClassName(Object obj) { System.out.println("The Object's class is " + obj.getClass().getName()); }
Ha tudjuk az osztly nevt, kaphatunk egy Class objektumot az osztlynvbl. A kvetkez kt sor egyarnt ugyanazon vgeredmnyt produklja (a msodik vltozat hatkonyabb):
String.class Class.forName("String")
12.rklds
127. oldal
Biztonsg: Az egyik mdszer, amit a hackerek hasznlnak rendszerek feltrsnl, egy szrmaztatott osztly ltrehozsa egy osztlybl, majd helyettestse az eredetivel. A szrmaztatott osztly a metdushvs szempontjbl gy nz ki, mint az eredeti, de a viselkedse teljesen ms is lehet, ami hibs mkdst eredmnyezhet. Ennek elkerlse rdekben deklarlhatjuk osztlyunkat vglegess, mely megakadlyozza a szrmaztatott osztlyok ltrehozst. A String osztly is vgleges. Ez az osztly nlklzhetetlen a Java Platform mkdshez. Ez biztostja, hogy minden String a megfelel mdon mkdjn. Ha megprbljuk lefordttatni egy final osztly leszrmazott osztlyt, hibazenetet fogunk kapni. Tervezs: Az objektumorientlt tervezsnl rdemes megllaptani, hogy mely osztlyokat szeretnnk vglegess tenni, s tegyk is az adott osztlyokat vglegess a final mdost segtsgvel:
final class ChessAlgorithm { ... }
Vgleges metdusok
A final kulcsszt hasznljuk a deklarciban, ha azt akarjuk elrni, hogy ne lehessen a metdust szrmaztatott osztlyban felldefinilni. Az Object metdusai kzl van, amelyik final tpus, s van, amelyik nem. A kvetkez pldban a ChessAlgorithm osztlyban a nextMove metdus tesszk vglegess:
class ChessAlgorithm { ... final void nextMove(ChessPiece pieceMoved, BoardLocation newLocation) { ... } ... }
128. oldal
Hogyan lehet hivatkozni a leszrmazott osztlyban az s elrejtett adattagjra? Mire hasznlhat a super kulcssz? Milyen esetben szksges az sosztly konstruktort explicit meghvni?
Melyik egy publikus, absztrakt metdus helyes deklarcija? public abstract void add(); public abstract void add() {} public virtual add();
A leszrmazott osztly konstruktorban hova kell rni a szlosztly konstruktornak hvst? akrhova a konstruktor els sorba a konstruktor utols sorba nem kell meghvni
13.Begyazott osztlyok
129. oldal
13.Begyazott osztlyok
Megadhatunk egy osztlyt egy msik osztly tagjaknt. Egy ilyen osztlyt begyazott osztlynak hvunk, s a kvetkezkppen nz ki:
class EnclosingClass { ... class ANestedClass { ... } }
A begyazott osztlyokat arra hasznljuk, hogy kifejezzk s rvnyestsk kt osztly kztt a kapcsolatot. Megadhatunk egy osztlyt egy msik osztlyon bell, hogyha a begyazott osztlynak a magba foglal osztlyon belli krnyezetben van rtelme. Pl. a szvegkurzornak csak a szvegkomponensen belli krnyezetben van rtelme. A begyaz osztly tagjaknt a begyazott osztly kivltsgos helyzetben van. Korltlan hozzfrssel rendelkezik a begyaz osztlyok tagjaihoz mg akkor is, hogy ha azok privtknt vannak deklarlva. Azonban ez a specilis kivltsg nem mindig specilis. A hozzfrst biztost tagok korltozzk a hozzfrseket az olyan osztlytagokhoz, amelyek a begyaz osztlyon kvl esnek. A begyazott osztly a begyaz osztlyon bell tallhat, ebbl kifolylag hozzfrhet a begyaz osztly tagjaihoz. Mint ahogyan ms tagokat is, a begyazott osztlyokat is statikusknt, avagy nem statikusknt lehet deklarlni, ezrt ezeket pontosan gy is hvjk: statikus begyazott osztly. A nem statikus begyazott osztlyokat bels osztlyoknak hvjuk.
class EnclosingClass { ... static class StaticNestedClass { ... } class InnerClass { ... } }
Ahogy a statikus metdusok s vltozk esetn, amelyeket mi osztlymetdusoknak s vltozknak hvunk, a statikus begyazott osztlyt a begyaz osztlyval kapcsoljuk ssze. Ahogy az osztlymetdusok, a statikus begyazott osztlyok sem hivatkozhatnak kzvetlenl olyan pldnyvltozkra vagy metdusokra, amely az begyaz osztlyban van megadva. A pldnymetdusok s vltozk esetn egy bels osztly az begyaz osztlynak a pldnyval kapcsoldik ssze, s kzvetlen hozzfrse van annak az objektumnak a pldnyvltozihoz s metdusaihoz. Mivel egy bels osztlyt egy pldnnyal trstanak, ezrt nmaga nem definilhat akrmilyen statikus tagot. Hogy a tovbbiakban knnyebb legyen megklnbztetni a begyazott osztly s a bels osztly fogalmt, rdemes ezekre a kvetkezflekppen tekinteni: a begyazott osztly kt osztly kztti szintaktikus kapcsolatot fejez ki, azaz szintaktikailag az egyik osztlyban lev kd megtallhat a msikon bell. Ezzel ellenttben a bels osztly olyan objektumok kztti kapcsolatot fejez ki, amelyek kt osztlynak a pldnyai. Tekintsk a kvetkez osztlyokat:
130. oldal
class EnclosingClass { ... class InnerClass { ... } }
Az e kt osztly kztti kapcsolatnl nem az az rdekes, hogy az InnerClass szintaktikusan definilva van az EnclosingClass-on bell, hanem az, hogy az InnerClass-nak a pldnya csak az EnclosingClass-nak a pldjn bell ltezhet, s kzvetlen hozzfrse van a pldnyvltozk s a begyaz osztly pldnymetdusaihoz. A begyazott osztlyok mindkt fajtjval tallkozhatunk a Java API-n bell, s kell is hasznlni ket. Azonban a legtbb begyazott osztly, amelyeket hasznlunk, valsznleg bels osztly lesz.
Az Iterator definilja azt az interfszt, ami vgigmegy egyszer az elemeken egy megadott sorrend szerint, amelyet a kvetkezkppen adunk meg:
while (hasNext()) { next(); }
A Stack osztly nmaga nem tudja vgrehajtani az Iterator interfszt, mert az Iterator interfsz API-ja bizonyos korltokat szab: kt klnbz objektum nem listzhatja kis egyszerre a veremben lv elemeket. Ugyanis nincs lehetsg arra, hogy megtudjuk, ki hvja meg a kvetkez metdust, s a listzst nem lehet jraindtani, mert az Iterator interfsznek nincsen olyan metdusa, amely tmogatn ezt. gy a kilistzst csak egyszer lehet vgrehajtani, mert az Iterator interfsznek nincs arra metdusa, hogy az elejhez visszamenjen a bejrs. Ehelyett egy bels osztly van, amely elvgzi a verem szmra ezt a munkt. A bels osztly hozzfrhet a verem elemeihez, s mr csak azrt is hozz kell, hogy tudjon frni, mert a veremnek a publikus interfsze csak LIFO hozzfrst tmogat. Itt lp be a kpbe a bels osztly. Itt lthat egy verem implementci, ami definil egy bels osztlyt, amelyet StackIterator-nak hvunk, s kilistzza a verem elemeit.
public class Stack { private Object[] items; public Iterator iterator() { return new StackIterator(); }
13.Begyazott osztlyok
class StackIterator implements Iterator { int currentItem = items.size() - 1; public boolean hasNext() { ... } public Object next() { ... } public void remove() { ... } } }
131. oldal
Figyeljk meg, hogy a StackIterator osztly kzvetlenl hivatkozik a veremben lev elemek pldnyainak vltozira. A bels osztlyokat elssorban arra hasznljuk, hogy implementljuk a segt osztlyokat, gy, mint itt, ebben a pldban is lthatjuk. Ha GUI esemnyeket akarunk hasznlni, akkor ismernnk kell a bels osztlyok hasznlatnak a szablyait, mert az esemnykezels mechanizmusa elg erteljesen hasznlja ezeket. Deklarlhatunk egy bels osztlyt anlkl, hogy nevet adnnk neki. Az ilyen osztlyokat nvtelen osztlyoknak hvjuk. Itt lthat mg egy vltozata a Stack osztlynak, ebben az esetben nvtelen osztlyt hasznlunk az Iterator szmra.
public class Stack { private Object[] items; public Iterator iterator() { return new Iterator() { int currentItem = items.size() - 1; public boolean hasNext() { ... } public Object next() { ... } public void remove() { ... }
} } }
A nvtelen osztlyok nehzkess tehetik a kd olvasst, ezrt csak olyan osztlyokhoz rdemes hasznlnunk, amelyek nagyon kicsik (nem tbb mint egy-kt metdus), s amelyek hasznlata elgg egyrtelm, mint pldul az esemnykezel osztly.
132. oldal
gyazott osztly deklarlhat brmilyen kdblokkon bell. A begyazott osztly, amely egy metduson vagy egy msik kdblokkon bell van deklarlva, hozzfrhet brmilyen hatkrn belli vgleges vagy loklis vltozhoz.
14.Felsorols tpus
133. oldal
14.Felsorols tpus
A felsorols tpus egy olyan tpus, melynek megengedett rtkei fix konstansokbl llnak. Javban a felsorols tpust enum szval definiljuk. Pl. a ht napjait gy definilhatjuk:
enum Days { VASARNAP, HETFO, KEDD, SZERDA, CSUTORTOK, PENTEK, SZOMBAT}; }
Vegyk szre, hogy konvencionlisan a nevek a felsorols tpusnl nagy betkkel randk, gy a kd olvassnl knnyen felismerhetk a konstansok. Brmikor hasznlhatunk felsorols tpust, ha szksgnk van kttt konstans rtkekre. Ez magban foglalja a termszetes felsorols tpusokat, mint a Naprendszer bolygi, a ht napjai, krtyapakli lapjainak neve/rtke s minden olyan esetet, ahol az sszes lehetsges tket tudjuk a fordtskor. A Java programozsi nyelv felsorols tpusa sokkal hatkonyabb, mint ms nyelvekben szerepl megfeleli, melyek csak nevestett egsz szmok. Az enum deklarci egy osztlyt definil, gynevezett enum tpust, melynek legfontosabb jellemzi a kvetkezk: Beszdesebbek az egyszer literloknl Tpusbiztosak Sajt nvterk van rdemes switch-case szerkezetben felsorolsi tpus alapjn szervezni Van egy statikus values metdusuk, mely egy tmbt ad vissza, melyben a tpus rtkei szerepelnek deklarlsi sorrendben. Ez a mdszer pl. for-each ciklussal nagyon hasznos. Tartalmazhat metdusokat, adattagokat, implementlhat interfszeket stb. Minden Object metdust implementlnak. sszehasonlthatk s szerializlhatk.
A kvetkez pldban a Planet egy felsorols tpus, mely a Naprendszer bolygit jelenti meg. A bolygnak van egy konstans tmeg s sugr paramtere. Minden konstanst tmeggel s sugrral deklarlnak, melyet tadnak a konstruktornak a ltrehozskor. Vegyk szre, hogy a felsorols tpus konstruktora rtelemszeren privt. Ha megprblunk egy publikus konstruktort ltrehozni a felsorols tpusnak, akkor a fordt hibazenetet fog visszaadni.
public enum MERCURY VENUS EARTH MARS JUPITER SATURN URANUS NEPTUNE PLUTO Planet { (3.303e+23, (4.869e+24, (5.976e+24, (6.421e+23, (1.9e+27, (5.688e+26, (8.686e+25, (1.024e+26, (1.27e+22, 2.4397e6), 6.0518e6), 6.37814e6), 3.3972e6), 7.1492e7), 6.0268e7), 2.5559e7), 2.4746e7), 1.137e6);
134. oldal
A bolygnak az rtkei mellett metdusai is vannak, melyeken keresztl kinyerhet a felszni gravitci s egy trgy slya minden bolygn. A kvetkez pldaprogram egy ember Fldn mrt slya alapjn kiszmolja, majd kirja ugyanennek az embernek a slyt minden bolygn.
public static void main(String[] args) { double earthWeight = Double.parseDouble(args[0]); double mass = earthWeight/EARTH.surfaceGravity(); for (Planet p : Planet.values()) { System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass)); } }
A kimenet:
$ java Planet 175 Your weight on MERCURY is 66.107583 Your weight on VENUS is 158.374842 Your weight on EARTH is 175.000000 Your weight on MARS is 66.279007 Your weight on JUPITER is 442.847567 Your weight on SATURN is 186.552719 Your weight on URANUS is 158.397260 Your weight on NEPTUNE is 199.207413 Your weight on PLUTO is 11.703031
Csak egyetlen megktse van a felsorols tpusnak: habr a felsorols tpusok osztlyok, nem definilhat hierarchia szmukra. Ms szavakkal: nem lehet leszrmazottja a felsorolsi tpusnak. Vgezetl a java.util csomag tartalmaz kt specilis Set s Map implementcit, mely tmogatja a felsorols tpusokat, az EnumSet-et s az EnumMap-et.
15.ltalnos programozs
135. oldal
15.ltalnos programozs
Az ltalnos (generikus) programozs tpusparamterek segtsgvel teszi lehetv, hogy osztlyokat, interfszeket hozhassunk ltre gy, hogy bizonyos paramterek tpusait a pldnyostskor dnthessk el.
Vegyk szre, hogy a T tpus paramter bevezetsre kerlt az osztlynv utn, s ezek utn feltnik, mint a push metdus paramter tpusa, s a pop metdus visszatrsi tpusa. A gyjtemnyek gyakran hasznlatosak arra, hogy bemutassuk az ltalnos tpus hasznlatt, mivel nagyon jellemzek az interfszekben s osztlyokban. A valsgban a gyjtemnyek voltak a f motivcis er az ltalnos tpusok bevezetsnl a Java nyelvben, mivel elrhetv teszik a fordts idej ellenrzst a gyjtemnyeken vgzett mveletek tpusbiztonsgnak. Amikor specifikljuk egy gyjtemnyben trolt objektum tpust: a fordt tud ellenrizni brmilyen mveletet, ami egy objektumot ad a gyjtemnyhez ismert az objektum tpusa, mely a gyjtemnybl lett kinyerve, ezrt nincs szksg arra, hogy cast-oljuk (talaktsuk) tpuss. Ugyanakkor nincs lehetsg arra sem, hogy talaktsunk egy rossz tpuss, s ekkor megtapasztaljunk egy futs idej ClassCastException kivtelt.
Ahogy az elbbiekben rtuk, ha egy ltalnos tpust hasznlunk, helyettestjk a paramter egy aktulis tpus paramtert, nagyjbl ugyanezen mdszerrel helyettestnk egy metdushoz a paramtereihez tartoz aktulis rtkeket. Egy aktulis tpus paramternek referencia tpusnak kell lenni, nem lehet primitv. Pldul, itt lthat az, hogy hogyan lehet ltrehozni Stack2-t String tpus paramterrel; s ezek utn push-olni s popolni a hi String-et.
136. oldal
Stack2<String> s = new Stack2<String>(); s.push("hi"); String greeting = s.pop(); //no cast required here
Vegyk szre, hogy amikor az ltalnos tpust hasznljuk, akkor a fordt egy olyan technikval fordtja le az ltalnos tpust, amit tpus trlsnek hvnak. Gyakorlatilag a fordt trli az sszes olyan informcit, mely a tpus paramterrel, vagy a tpus paramterekkel kapcsolatos. Pldul a Stack2<string> tpust lefordtja Stack2re, melyet nyers tpusnak neveznek. Abbl kvetkeztethetnk a tpus trlsre, hogy a tpus paramter nem rhet el futsidben ahhoz, hogy hasznljuk tpusknyszertsben, vagy mint az instanceof eljrs paramtere.
Vlaszthatnnk, hogy ltrehozunk egy String listt s ezt a metdust hasznljuk az szszes String kiratsra:
List<String> list = new ArrayList<String>(); ... printall(list); //error
Ha ezt hasznljuk, akkor szre fogjuk venni, hogy az utols sor fordtsi hibt ad. Mivel az ArrayList<String> nem leszrmazott tpusa a Collection<Object>-nek, ezrt nem adhat t, mint paramter a kiratsi eljrsnak annak ellenre, hogy a kt tpus ugyanannak az ltalnos tpusnak a leszrmazottai, rokon rkltt tpus paramterekkel. Ms rszrl az rkls miatt kapcsolatban ll ltalnos tpusok ugyanazzal a tpus paramterrel kompatibilisek:
public void printAll(Collection<Object> c) { for (Object o : c) { System.out.println(o); } } List<Object> list = new ArrayList<Object>(); ... printall(list); //this works
15.ltalnos programozs
137. oldal
A List<Object> kompatibilis a Collection<Object>-el, mert a kt tpus pldnya egy ltalnos szltpusnak s annak leszrmazott tpusnak, s a pldnyok ugyanahhoz a tpus paramterhez tartoznak, konkrtan az Object-hez.
A ?-es tpus hatrozatlan tpusknt ismert. A gyjtemnybl brmikor kiolvashat az objektum, mert a visszatrsi rtk mindig garantltan Object. Azonban nem adhat objektum a gyjtemnyhez, mert a ? ismeretlen tpust jell, s nem lehet egyrtelmen tudni, hogy a hozz adni kvnt objektum leszrmazott tpusa-e az ismeretlen tpusnak. Az egyetlen kivtel a null, amely eleme minden tpusnak. Korltozhatjuk (vagy knyszerthetjk) is a helyettest tpust valamely tpus segtsgvel. A korltozott helyettest tpus akkor hasznos, mikor csak rszben ismerjk a paramtereket. Pldul tegyk fel, hogy van egy osztly hierarchink geometriai alakzatokbl (Shape), s ennek leszrmazott tpusaibl (Circle, Rectangle, s gy tovbb). A rajzol program, ami ezekre az objektumokra hivatkozik, meghv egy drawAll nev metdust, hogy egy gyjtemnyt rajzoljon ezekbl az alakzatokbl:
public void drawAll(Collection<Shapes> shapes) { for (Shape s: shapes) { s.draw(); } }
Mivel lthattuk, hogy nem megengedett a Shape tpus valamely leszrmazott tpusnak (pldul a Circle) alkalmazsa, ezrt ez a metdus csak korltozottan hasznlhat: pldul nem hvhat meg a Collection<Circle> esetn. Hogy lehetv tegyk a Shape tpus valamely leszrmazott tpusnak tpus paramterknt val alkalmazst, kiterjeszthetjk az alakzatok gyjtemny tpus paramtert helyettest tpusknt. De mivel tudjuk, hogy a tpus paramter valamilyen alakzat lesz, a helyettestst korltozhatjuk a Shape tpusra a kvetkezkppen:
void drawAll(Collection<? extends Shapes> shapes) { ... }
Ez lehetv teszi a drawAll szmra, hogy elfogadjon brmilyen, a Shape tpus leszrmazott tpusbl ll gyjtemnyt. sszefoglalva, a helyettest tpus fels korltozssal specializlhat a <? extends Type> mdon, ezltal megfelelv tve az adott Type minden leszrmazott tpushoz. A helyettest tpust alulrl is korltozhatjuk. Egy alulrl korltozott helyettest a <? super Type> mdon rhat le, s a Type minden sosztlyra hasznlhat. Megfigyelhetjk, hogy tovbbra sem lehetsges ismeretlen tpus gyjtemnyhez objektumot hozzadni, s ez nem lehetsges korltozott, ismeretlen tpus gyjtemny esetn sem.
138. oldal
Az ltalnos metdusok lehetv teszik a tpus paramterek hasznlatt, hogy egyrtelmv tehesse a tpusok kapcsolatt egy vagy tbb paramter esetn, egy metdus, vagy annak visszatrsi rtke szmra (vagy mindkettnek). Az ltalnos metdusok tpus paramterei ltalban osztlytl fggetlenek vagy interfsz-szint tpus paramterek. A Collections osztly algoritmusainak defincija sok lehetsget knl az ltalnos metdusok hasznlatra. Az egyetlen klnbsg az ltalnos tpusok s ltalnos metdusok kztt az, hogy az ltalnos metdusokat hagyomnyos metdusknt hvjuk meg. A tpus paramtereket a hvs fggvnyben llaptjuk meg, ahogy a fill metdus albbi hvsnl is:
public static void main(String[] args) { List<String> list = new ArrayList<String>(10); for (int i = 0; i < 10; i++) { list.add(""); } String filler = args[0]; Collections.fill(list, filler); ...
Megfigyelhet, hogy a Collection objektum hatrozatlan tpus: a gyjtemnyben lv objektumok tpusa nem meghatrozott. Azonos helyzet llt fenn minden tovbbi metdusnl is, melyek objektumot adnak vissza, mg mieltt az ltalnos tpusok elrhetv vltak volna a Java 5.0-s verziban. Tegyk fel, hogy runk egy programot Cats nven, mely ezt a visszatrsi rtket adja t egy gyjtemnynek, melynek tpusa kifejezetten Cat kell, hogy legyen:
15.ltalnos programozs
public static void main(String[] args) { Collection<Cat> litter = myCat.getLitter(3); for (Cat c : litter) { System.out.println(c.getColor()); }
139. oldal
sszegezve, ha a Cat-et olyan fordtval fordtjuk jra, mely tmogatja a tpus paramtereket, a kvetkez figyelmeztetst kapjuk:
% javac -Xlint:unchecked Cat.java Cat.java:19: warning: [unchecked] unchecked call to add(int,E) as a member of the raw type java.util.ArrayList litter.add(i, new Cat()); ^
Habr a kd hibtlan, ez a figyelmeztets mutatja, hogy a fordt nem tudja biztostani a mvelet pontossgt, mikor specilis tpus gyjtemnyeket hasznlunk. Amikor ellenrizetlen figyelmeztetst kap, ellenriznie kell, hogy a mvelet, mely a figyelmeztetst generlta, valban megfelel-e. Vgl tekintsnk t egy listt a teljes Stack2 osztlyrl:
public class Stack2<T> implements Cloneable { private ArrayList<T> items; private int top=0; public Stack2() { items = new ArrayList<T>(); } public void push(T item) { items.add(item); top++; } public T pop() { if (items.size() == 0) throw new EmptyStackException(); T obj = items.get(--top); return obj; } public boolean isEmpty() { if (items.size() == 0) return true; else return false; }
140. oldal
Megfigyelhetjk, hogy a clone metdus a clone metdusokat az sosztlybl s a tartalmazott listjbl hvja meg. A clone metdusok rkld metdusok, mert mg az ltalnos tpusok elrhetsge eltt definilva lettek. Mikor lefordtja a Stack2.java llomnyt, a kvetkez figyelmeztetst kapja:
% javac -Xlint:unchecked Stack2.java Stack2.java:32: warning: [unchecked] unchecked cast found : java.lang.Object required: Stack2<T> Stack2<T> s = (Stack2<T>)super.clone(); ^ Stack2.java:33: warning: [unchecked] unchecked cast found : java.lang.Object required: java.util.ArrayList<T> s.items = (ArrayList<T>)items.clone(); ^ 2 warnings
Ez a figyelmeztets mutatja, hogy a fordt nem kpes biztostani az eljrs kifogstalan mkdst. Ms szval, mivel a clone metdust gy definiltk, hogy egy Object osztlybeli objektumot adjon visszatrsi rtknek, ezrt a fordt nem tudja biztostani, hogy a gyjtemny visszatrsi rtke Stack2<T> legyen. Azonban a clone metdus feletti megllapods szerint a mvelet engedlyezett, habr ellenrizetlen figyelmeztetst okoz. Rengeteg apr dologra kell figyelni az ltalnos tpusok hasznlatnl az rklsben.
16.Interfszek
141. oldal
16.Interfszek
Az interfsz olyan viselkedseket definil, amelyet az osztlyhierarchia tetszleges osztlyval megvalsthatunk. Egy interfsz metdusok halmazt definilja, de nem valstja meg azokat. Egy konkrt osztly megvalstja az interfszt, ha az sszes metdust megvalstja. Definci: Az interfsz implementci nlkli metdusok nvvel elltott halmaza. Mivel az interfsz a megvalsts nlkli, vagyis absztrakt metdusok listja, alig klnbzik az absztrakt osztlytl. A klnbsgek: Az interfsz egyetlen metdust sem implementlhat, az absztrakt osztly igen. Az osztly megvalsthat tbb interfszt, de csak egy sosztlya lehet. Az interfsz nem rsze az osztlyhierarchinak. Egymstl "fggetlen" osztlyok is megvalsthatjk ugyanazt az interfszt.
Ebben a fejezetben egy olyan pldaprogramot fogjuk hasznlni, ami a Tervezsi mintk (Design Patterns) kztt szoks emlegetni megfigyel (Observer) nven. Ez az osztly megengedi ms osztlyoknak, hogy regisztrljk magukat bizonyos adatai vltozsnak figyelsre. A StockApplet osztly fog megvalstani egy olyan metdust, amivel regisztrlni tud a vltozs figyelshez:
public class StockMonitor { public void watchStock(StockWatcher watcher, TickerSymbol tickerSymbol, BigDecimal delta) { ... } }
Az els paramter egy StockWatcher objektum. A StockWatcher annak az interfsznek a neve, amelyet hamarosan ltni fogunk. Az interfsz egyetlen valueChanged nev metdust definil. Egy objektum akkor tudja magt megfigyelknt regisztrlni, ha az osztlya megvalstja ezt az interfszt. Amikor a StockMonitor osztly rzkeli a vltozst, meghvja a figyel valueChanged metdust.
A StockWatcher interfsz deklarlja, de nem implementlja a valueChanged metdust. Az interfszt megvalst osztlyok fogjk a metdust implementlni.
142. oldal
Interfsz deklarci
A kvetkez bra az interfsz deklarci minden rszt bemutatja:
Az interfsz deklarciban kt elem ktelez: az interface kulcssz s az interfsz neve. Ez utn szerepelhetnek a szlinterfszek.
Az interfsz trzs
Az interfsz trzs metdus deklarcikat tartalmaz ';'-el lezrva. Minden deklarlt metdus rtelemszeren publikus s absztrakt (br maguk a kulcsszavak nem rhatk ki). Az interfsz tartalmazhat konstans deklarcit is. Minden konstans rtelemszeren publikus, statikus s vgleges. (A kulcsszavak itt sem rhatk ki.) Nem hasznlhatk a transient, volatile, synchronized, private s protected mdostk sem.
16.Interfszek
public class StockApplet extends Applet implements StockWatcher { public void valueChanged(TickerSymbol tickerSymbol, BigDecimal newValue) { switch (tickerSymbol) { case SUNW: ... break; case ORCL: ... break; case CSCO: ... break; default: // handle unknown stocks ... break; } }
143. oldal
Amikor egy osztly megvalst egy interfszt, akkor alapveten alr egy szerzdst. Az osztlynak implementlni kell az interfszben s szlinterfszeiben deklarlt sszes metdust, vagy az osztlyt absztraktknt kell deklarlni. (Az ilyen absztrakt osztlyoknak csak akkor lehet nem absztrakt egy leszrmazottja, ha az ezen az rklsi szinten meg nem valstott metdusokat mr maradktalanul megvalstja.) A StockApplet megvalstja a StockWatcher interfszt, azaz szolgltatsknt nyjtja a valueChanged metdust.
Ha egy osztly megvalst egy interfszt, azt a uses kulcsszval kell jelezni. Az interfsz sszes metdusa implicit abstract. Az interfsz sszes vltozja implicit public. Az interfszt megvalst osztlynak minden, az interfszben deklarlt metdust implementlni kell. Ltre lehet hozni interfsz-referencit. Minden interfsznek van se. Az interfsz sszes vltozja implicit final. Minden interfszt legalbb egy osztlyban meg kell valstani. Az interfsz metdusainak nincs trzse. Az interfsz s az absztrakt osztly kztt nincs lnyeges klnbsg.
17.Csomagok
145. oldal
17.Csomagok
A tpusok knnyebb megtallshoz s hasznlathoz, nvtkzsek elkerlshez s az elrs szablyozshoz a programozk egybe csomagolhatjk az sszetartoz tpusaikat csomagokk. Definci: A csomag sszetartoz tpusok gyjtemnye. A Java platform tpusai funkcik szerint klnbz csomagokba vannak szervezve: az alapvet osztlyok a java.lang csomagban, az I/O osztlyok a java.io-ban, s gy tovbb. Ezen kvl a sajt tpusainkat is tehetjk csomagokba. A kvetkez osztlyokat megvizsglva ltszik, hogy kzs csomagba rdemes ket sorolni, mivel grafikus objektumok csoportjba tartoznak a krk, tglalapok, vonalak s pontok. Ha runk egy Draggable interfszt, az azt megvalst osztlyok lehetv teszik a vonszolst is.
//in the Graphic.java file public abstract class Graphic { . . . } //in the Circle.java file public class Circle extends Graphic implements Draggable { . . . } //in the Rectangle.java file public class Rectangle extends Graphic implements Draggable { . . . } //in the Draggable.java file public interface Draggable { . . . }
A kvetkez okok miatt rdemes az osztlyokat s interfszeket kzs csomagba helyezni: Ms programozk szmra is ltszik, hogy kapcsold tpusokrl van sz. Ms programozk is lthatjk, hol kell keresni a grafikhoz kapcsold osztlyokat. A tpusaink nevei nem kerlnek sszetkzsbe ms csomagok neveivel, mert a csomagok nll nvtereket hoznak ltre. A tpusaink korltlanul lthatjk egymst, de egyb tpusok csak korltozottan frhetnek a tpusokhoz.
146. oldal
package graphics;
Ez utn a graphics csomag sszes forrskdja elejn ugyanezt a csomagmegjellst kell alkalmaznunk, hogy kzs csomagba kerljenek:
package graphics; public class Rectangle extends Graphic implements Draggable { . . . }
Ha nem alkalmazunk csomagmegjellst, akkor az osztly(ok) egy gynevezett alaprtelmezett nv nlkli csomagba kerlnek.
17.Csomagok
147. oldal
A kvetkezkppen hasznlhatjuk a minstett nevet, hogy ltrehozzuk a graphics.Rectangle osztly egy pldnyt:
graphics.Rectangle myRect = new graphics.Rectangle();
Ha minstett neveket hasznlunk, valsznleg bosszant lesz, hogy jra s jra be kell gpelni a graphics.Rectangle-t. Ezen kvl rendezetlen s nehezen olvashat programot kapunk. Ilyen esetekben inkbb importljuk a tagot.
Ez a szemllet akkor mkdik jl, ha csak nhny tagot hasznlunk a graphics csomagbl. De ha sok tpust hasznljuk egy csomagnak, akkor inkbb importljuk az egsz csomagot.
Most mr hivatkozhatunk brmelyik osztlyra vagy interfszre a graphics csomagbl az egyszer rvid nevvel:
Circle myCircle = new Circle(); Rectangle myRectangle = new Rectangle();
Az import utastsban a csillag karakterrel az sszes osztlyt megadjuk a csomagnak. Nem hasznlhatunk olyan megfeleltetst, amely egy csomagban egy osztly rszhalmazra utal. Pldul helytelen megfeleltets az, hogy a graphics csomagbl az A betvel kezdd sszes osztly importljuk:
import graphics.A*;
Ez az utasts fordtsi hibt generl. Az import utastssal, egy csomagnak egyetlen tagjt vagy egsz csomagot importlhatunk. Ugyangy nem megengedett, hogy egyszerre tbb csomagot importljunk, pl.:
import graphics.*.*;
148. oldal
Megjegyzs: Ha kevesebb tagot akarunk importlni, akkor megengedett, hogy csak egy osztlyt, s annak a bels osztlyait importljuk. Pldul, ha a graphics.Rectangle osztlynak a bels osztlyait akarjuk hasznlni, mint Rectangle.DoubleWide s Rectangle.Square, a kvetkez kpen importlhatjuk:
import graphics.Rectangle.*;
Knnytsl a Java fordt automatikusan importl hrom teljes csomagot: A nvtelen csomagot (ha nem hozunk ltre csomagot, vagyis nem hasznljuk a package utastst) Az alaprtelmezs szerinti aktulis csomagot (ha ltrehozunk csomagot) A java.lang csomagot
Megjegyzs: A csomagok nem hierarchikusak. Ha pldul importljuk a java.util.*-ot, nem hivatkozhatunk a Pattern osztlyra. Minden esetben gy kell hivatkoznunk, hogy java.util.regex.Pattern, vagy ha importljuk a java.util.regex.*-ot, akkor csak egyszeren Pattern.
Nvtkzs megszntetse
Ha egy tag ugyanazon a nven megtallhat egy msik csomagban, s mindkt csomag importlva van, akkor a tagra teljes nevvel kell hivatkoznunk. Pldul a Rectangle osztly definilva van a graphics csomagban, s a java.awt csomagban is. Ha a graphics s java.awt is importlva van, akkor a kvetkez nem egyrtelm:
Rectangle rect;
Az ilyen esetekben a minstett nevet kell hasznlnunk, hogy pontosan meg tudjuk adni, melyik Rectangle osztlyt akarjuk hasznlni:
graphics.Rectangle rect;
A csomag tag teljes neve s a fjl elrsi tja hasonl: Osztly nv Fjl elrsi t graphics.Rectangle graphics\Rectangle.java
17.Csomagok
149. oldal
Emlkezznk vissza, hogy a megllapods rtelmben a cgek fordtott internet domn nevet hasznlnak a csomagok elnevezsre. A pldban a cg domn neve hobnob.com, ezrt mindegyik csomagnak a nevt com.hobnob fogja megelzni. A csomag nvnek mindegyik sszetevje megegyezik egy-egy alknyvtrral. gy ha Hobnob-nak van egy graphics csomagja, amely tartalmazza a Rectangle.java forrsfjlt, akkor ezek alknyvtrak sorozatban troldnak:
Mikor lefordtjuk a forrsllomnyt, a fordt ltrehoz klnbz kimeneti llomnyt minden egyes definilt osztlynak s interfsznek. A kimeneti llomnynak az alap neve az osztly vagy interfsz neve s a kiterjesztse: .class, ahogyan a kvetkez bra is mutatja:
A .class fjlnak ugyangy, mint egy .java fjlnak is kell a csomagokat kifejez knyvtrszerkezet. Azonban nem lehet ugyanabban a knyvtrban, mint a forrs. Kln-kln knyvtrba kell rendezni a forrst s az osztlyt:
Ha ez alapjn csinljuk, oda tudjuk adni az osztly knyvtrakat ms programozknak anlkl, hogy megmutatnnk a forrsunkat. Ekkor hasznlhatjuk a Java fordtnak a d opcijt az osztly fjlok megadshoz, ehhez hasonlan:
javac d classes sources\com\hobnob\graphics\Rectangle.java
150. oldal
A forrs s osztly llomnyok kezelshez erre a mdszerre van szksgnk, gy a fordt s a Java virtulis gp (JVM) megtallja az sszes tpust, amit a programunk hasznl. Mikor a fordt sszeakad egy j osztllyal a program fordtskor, meg fogja tallni az osztlyt, gy hogy feloldja a neveket, tpusvizsglatot hajt vgre s gy tovbb. Hasonlan, amikor a JVM sszeakad egy j osztllyal program futskor, meg fogja tallni az osztlyhoz tartoz metdusokat. A fordt s a JVM az osztlyokat a class pathban listzott knyvtrakban s JAR fjlokban keresi. Definci: A class path, knyvtrak vagy JAR fjlok egy rendezett listja, amelyben class fjlokat kereshetnk. Fizikailag ez egy CLASSPATH nev krnyezeti vltozt jelent. Mindegyik knyvtr listzva van a class path-ban egy legfels szinten lv knyvtrban, amelyben csomag knyvtrak lthatk. A legfels szint knyvtrtl a fordt s a JVM sszelltja az elrsi tnak a maradkt, az alaphoz a csomagot s az osztly nvnl az osztlyt. A fordt s a JVM is sszelltja az elrsi t nevet a .class fjlhoz a csomag teljes nevvel. Alaprtelmezsknt a fordt s a JVM az aktulis knyvtrban s a JAR fjlban keres, amely magba foglalja a Java krnyezeti class fjlokat. Ms szval, az aktulis knyvtr s a Java krnyezeti class fjlok automatikusan benne vannak a class path-ban. Legtbbszr az osztlyokat megtalljk ezen a kt helyen. gy nem kell aggdnunk az osztlyaink elrsi tja miatt. Nhny esetben azonban lehet, hogy meg kell adni osztlyaink elrsi tjt.
17.Csomagok Egy csomag csak publikus osztlyokat tartalmazhat. Egy fordtsi egysgben csak egy osztlyt lehet deklarlni.
151. oldal
Elnevezsi konvenci szerint a csomag neve nagybetvel kezddik, a tbbi kicsi. Egy fordtsi egysg ktelezen tartalmaz package deklarcit. Egy fordtsi egysg ktelezen tartalmaz import deklarcit. Ha az osztly deklarcijnl nem adunk meg lthatsgot, akkor arra a csomag ms osztlyaibl lehet hivatkozni.
Melyik a helyes sorrend egy forrsllomny esetn? package, import, class class, import, package import, package, class package, class, import
152. oldal
18.Kivtelkezels
A kivtel a kivteles esemny kifejezs rvidtse. Definci: A kivtel egy olyan esemny, amely a program vgrehajtsakor keletkezik, megszaktva az utastsok vgrehajtsnak normlis folyamatt. Ha egy metdusban hiba keletkezik, a metdus egy objektumot hoz ltre, melyet tad a futtatsi krnyezetnek. Az objektum melyet kivtel objektumnak neveznek tartalmazza az informcit a hibrl, annak tpusrl s a program llapotrl, amikor a hiba ltrejtt. Kivtel objektum ltrehozst s futtatsi rendszer ltal trtn kezelst kivteldobsnak hvjk. Miutn egy metdus eldob egy kivtelt, a futtat krnyezet megprbl a kezelsre tallni valamit. A lehetsges dolgok, melyek a kivtelt kezelik a meghvott metdusok rendezett listja abban a metdusban, ahol a hiba keletkezett. A metdusok listjt hvsi veremnek nevezzk.
A futtat rendszer tkutatja a hvsi vermet olyan metdus utn, mely tartalmaz kivtel kezelsre alkalmas kdblokkot. Ezt a blokkot kivtelkezelnek nevezzk. A keress abban a metdusban kezddik, ahol a hiba generldott, majd a hvsi verem metdusainak fordtott sorrendjben folytatdik. Mikor egy megfelel kezelt tall, a futtat rendszer, tadja a kivtelt a kezelnek. Egy kivtelkezel megfelel, ha az eldobott kivtel objektum tpusa megegyezik azzal a tpussal, melyet a kezel kezelni tud. A kivtelkezel kivlasztst gy is nevezik, hogy elkapni a kivtelt. Ha a futtatkrnyezet a metdusok tkutatsa utn sem tall megfelel kivtelkezelt, mint ahogy a kvetkez bra mutatja, a futtat rendszer (s ez ltal a program) lell.
18.Kivtelkezels
153. oldal
Hibk kezelsre hasznlt kivteleknek van nhny elnye a hagyomnyos hibakezelsi technikkkal szemben. (Ksbb visszatrnk a tmra.)
154. oldal
Az els vastag bets sor egy konstruktor hvsa. A konstruktor egy kimeneti folyamot inicializl. Ha a fjlt nem lehet megnyitni, a konstruktor IOException-t dob. A msodik vastag bets sor a Vector osztly elementAt metdust hvja meg, mely egy ArrayIndexOutOfBoundsException-t dob, ha az paramtereinek rtke tl kicsi (kisebb, mint nulla), vagy tl nagy (nagyobb, mint a vltozk szma, melyeket a Vector tartalmaz). Ha megprbljuk lefordtani a ListOfNumbers osztlyt, a fordt egy hibazenetet r ki a FileWriter konstruktor ltal dobott kivtelrl, de nem fog hibazenetet megjelenteni az elementAt ltal dobott hibrl. Ennek oka, hogy a konstruktor ltal dobott kivtel, IOException, ellenrztt kivtel, mg a msik, ArrayIndexOutOfBundsException, egy futsi idben keletkezett kivtel. A Java programozsi nyelv csak az ellenrztt kivtelek kezelst kveteli meg, teht a felhasznl csak egy hibazenetet fog kapni. Most, hogy megismerkednk a ListOfNumbers osztllyal s az abban eldobott kivtelekkel, kszen llunk egy kivtelkezel megrsra, mely ezeket a hibkat elkapja, s kezelni tudja.
18.Kivtelkezels
155. oldal
A try blokk
Egy kivtelkezel elksztsnek els lpse, hogy elhatroljuk a kdot, ami hibt dobhat a try blokkban. A try blokk ltalban gy nz ki:
try { code } catch and finally blocks ...
A pldakdban tallhat szegmens tartalmaz egy vagy tbb olyan sort, amely kivtelt dobhat. (A catch s a finally blokkokrl rszletes magyarzatot a kvetkez rszben tallhatunk.) Ahhoz, hogy egy kivtelkezelt ksztsnk a ListOfNumbers osztly writeList metdushoz, a writeList metdus kivtel-dob rszeit el kell hatrolnunk a try blokkal. Ezt tbbflekppen tehetjk meg. A programkd azon sorait, melyekrl felttelezzk, hogy kivtelt dobhatnak, try blokkba tesszk, s mindegyiknl gondoskodunk a kivtelek kezelsrl. Vagy pedig betehetjk az sszes writeList kdot egy egyszer try blokkba, s ehhez hozzkapcsolhatunk tbbfle kivtelkezelt. A kvetkezkben lthatjuk, hogy az egsz metdusra hasznljuk a try blokkot, mivel a szban forg kd nagyon rvid:
... private Vector vector; private static final int SIZE = 10; ... PrintWriter out = null; try { System.out.println("Entered try statement"); out = new PrintWriter(new FileWriter("OutFile.txt")); for (int i = 0; i < SIZE; i++) { out.println("Value at: " + i + " = " + vector.elementAt(i)); } } /// catch and finally statements ...
Amennyiben a kivtel bekvetkezik a try blokkon bell, a kivtel lekezelsre kerl a kivtelkezel ltal. Ahhoz, hogy a kivtelkezelst hozz tudjuk kapcsolni a try blokkhoz, utlag hasznlnunk kell catch blokkot is. A kvetkez rsz megmutatja, hogyan is kell ezt hasznlnunk.
Megjegyzs: A kivtelkezelssel ismerkedk esetn gyakori hiba, hogy csak a kivtelt eldob fggvnyhvst teszik a try blokkba. rdemes ezen a pldn tgondolni, hogy ha nem sikerlne az llomny megnyitsa, akkor semmi rtelme nem lenne a for ciklus lefutsnak. A fenti megoldsnl ez nem is fog bekvetkezni, hiszen a kivtel ltrejttekor a vezrls a teljes try blokkbl kilp.
A catch blokk
A try blokkhoz hozzilleszthetjk a kivtelkezelst, amennyiben egy vagy tbb catch blokkot hasznlunk kzvetlenl a try blokk utn. Semmilyen programkd nem lehet a try blokk vge s az els catch blokk kztt!
try { ... } catch (ExceptionType name) { ... } catch (ExceptionType name) { ... } ...
156. oldal
Minden catch blokk egy kivtelkezel, s azt a tpus kivtelt kezeli, amilyet a paramter tartalmaz. A paramter tpusa (ExceptionType) deklarlja a kivtel tpust, amit a kezel lekezel. A catch blokk tartalmazza azt a programkdot, amely vgrehajtsra kerl, amikor a kivtelkezelt meghvjuk. A futtatrendszer meghvja azt a kivtelkezelt, amelyik esetn az ExceptionType megfelel a dobott kivtel tpusnak. Itt lthat kt kivtelkezel a writeList metdushoz az ellenrztt kivtelek kt tpushoz, melyeket a try blokk dobhat:
try { ... } catch (FileNotFoundException e) { System.err.println("FileNotFoundException: "+e.getMessage()); throw new SampleException(e); } catch (IOException e) { System.err.println("Caught IOException: "+e.getMessage()); }
Mindkt kezel egy hibazenetet r ki. A msodik kezel semmi mst nem hajt vgre. Brmilyen IOException (I/O kivtel) elkapsa esetn (amit az els kezel nem kapott el), megengedi a programnak, hogy folytassa a futtatst. Az els kezel a kirand szvegek sszeillesztse sorn egy sajt definilt kivtelt dob. Ebben a pldban a FileNotFoundException kivtel ltrejttekor egy sajt definilt kivtelt hoz ltre, aminek SampleException a neve, s ezt dobja a program. A kivtelkezelk tbbet is tudnak, mint hogy hibazeneteket rnak ki, vagy pedig meglltjk a program futst. Hibajavtsra is kpesek, amint a felhasznl hoz egy rossz dntst, vagy pedig a hibk tlnnek a legmagasabb szint kezeln lncolt kivteleket hasznlva.
A finally blokk
A kivtelkezel belltsnak utols lpse, hogy rendet tegynk magunk utn, mieltt tadjuk az irnytst a program klnbz rszeinek. Ezt a takart programkdot a finally blokkba kell bernunk. A finally blokk tetszlegesen hasznlhat. Olyan mechanizmust nyjt, ami kikszbli azokat a figyelmetlensgeket, amik a try blokkban trtntek. A finally blokkot pldul arra hasznlhatjuk, hogy bezrjuk a fjlokat, amelyekre se a hiba nlkli futs, se a hiba dobsa esetn nem szksgesek mr. A writeList metdus try blokkja (amivel eddig dolgoztunk) megnyitja a PrintWriter-t. A writeList metdusbl val kilps eltt programnak be kellene zrnia ezt a folyamatot. Ez felvet egy nmikpp kompliklt problmt, mivel writeList metdus try blokkja a kvetkez hrom lehetsg kzl csak egyflekppen tud kilpni: A new FileWriter hibt jelez s IOException-t dob. A vector.elementAt(i) hibt jelez s ArrayIndexOutOfBoundsException-t dob. Minden sikerl s a try blokk zkkenmentesen kilp.
A futtatrendszer mindig vgrehajtja azokat az utastsokat, amelyek a finally blokkban vannak, fggetlenl attl, hogy trtnt-e kivtel dobsa, vagy nem. gy ez a legmegfelelbb hely, hogy kitakartsunk magunk utn. A kvetkez finally blokk a writeList metdust takartja ki, s bezrja a PrintWriter-t.
18.Kivtelkezels
finally { if (out != null) { System.out.println("Closing PrintWriter"); out.close(); } else { System.out.println("PrintWriter not open"); } }
157. oldal
A writeList pldban, a finally blokkba val beavatkozs nlkl tudunk gondoskodni a kitakartsrl. Pldul, a PrintWriter bezrst vgz programkdot a try blokk vghez tudjuk illeszteni, tovbb az ArrayIndexOutOfBoundsException kivtel-kezelhz:
try { ... out.close(); } catch (FileNotFoundException e) { out.close(); System.err.println( "Caught: FileNotFoundException: "+e.getMessage()); throw new RuntimeException(e); } catch (IOException e) { System.err.println("Caught IOException: " + e.getMessage()); }
Azonban ez mgis lemsolja a kdot, gy amennyiben ksbb mdostjuk a programkdot, nehz lesz olvasni benne, s a hibk kiterjedhetnek. Pldul, ha a try blokkhoz egy olyan programkddal bvtjk, ami egy j tpus kivtelt dobhat, emlkeznnk kell arra, hogy bezrjuk a PrintWriter-t az j kivtel-kezelben.
Az sszeilleszts
Az elz rszekben volt arrl sz, hogyan ptsnk fel a ListOfNumbers osztlyban try, catch s finally blokkokat a writeList metdus szmra. A kvetkezkben a forrskdot nzzk meg, vizsglva a vgeredmnyt. Mindent egybevve, a writeList metdus a kvetkezkpp nz ki:
public void writeList() { PrintWriter out = null;
158. oldal
Ahogy azt elzekben emltettk, a metdusban a try szerkezetnek hrom lehetsges kimenete lehet: A kdunk hibs s kivtelt dob. Ez lehet egy IOException kivtel, amit a FileWriter okoz vagy egy ArrayIndexOutOfBoundsException kivtel egy rosszul megadott rtk esetn a for ciklusban, esetleg egy RuntimeException kivtel brmilyen futsi hiba esetn. Minden rendben, a vrt kimenetet kapjuk.
Kivtel trtnik
Szmos oka lehet annak, hogy a FileWriter hibs mkdst fog eredmnyezni. Okozhatja a konstruktor (ha nem tudjuk ltrehozni a fjlt, vagy nem tudunk belerni). Amikor a FileWriter az IOException kivtelt dobja, a program azonnal lelltja a try blokk vgrehajtst. Ezek utn a rendszer a metdus elejtl indul, s meghvja a megfelel kivtelkezelt. Habr a FileWriter konstruktornak nincs megfelel kivtelkezelje, a rendszer megnzi a writeList metdust. A writeList metdusnak kt kivtelkezelje van: egyik az IOException, msik, pedig az ArrayIndexOutOfBoundsException. A rendszer megnzi a writeList kivtelkezelit, de csak a try blokk utn. Az els kivtelkezel nem foglalkozik a konkrt kivtel tpussal, ezrt a rendszer automatikusan a msodik kivtelkezelt hasznlja (IOException). Ez be tudja azonostani a tpust, ennek ksznheten a rendszer mr megtallja a megfelel kivtelkezelt, gy a catch blokk vgrehajtdik. Miutn a kivtelkezel lefutott, a rendszer a finally blokkra ugrik, melynek futsa elindul a kivteleket figyelmen kvl hagyva. Miutn a finally blokk lefutott a rendszer normlis temben fut tovbb.
159. oldal
A writerList metdus deklarcijban a throws kulcssz hozzadsval kt kivtelt adunk meg. A throws kulcsszt egy vesszvel elvlasztott lista kvet a kivtelosztlyokkal. A throws a metdus neve s a paramter lista utn ll, utna kvetkezik a kapcsos zrjelben a definci:
public void writeList() throws IOException, ArrayIndexOutOfBoundsException {
Az ArrayIndexOutOfBoundsException futsidej kivtel, nem ktelez lekezelni, gy elegend az albbi forma hasznlata:
public void writeList() throws IOException {
160. oldal
A Java platform szmos osztlyt nyjt a kivtelek kezelsre, melyek egytl egyig leszrmazottjai a Throwable osztlynak. Ezek az osztlyok lehetv teszik a programok szmra, hogy megklnbztessk az eltr tpus kivteleket, melyek a program futsa kzben keletkeznek. Sajt magunk is ltrehozhatunk specilis osztlyokat a leend problmk reprezentcijval. Fejlesztknt sajt magunknak kell ltrehoznunk az osztlyt s elvgezni a szksges belltsokat.
18.2.1
A throw hasznlata
A kivtel dobsnl minden metdus a throw kulcsszt hasznlja, melynek a kvetkez formai kvetelmnynek kell, hogy megfeleljen:
throw someThrowableObject;
Az albbi pop metdus egy osztly ltal ltrehozott kzs veremobjektumbl jn ltre. A metdus eltvoltja a verem fels rekeszt s az objektummal tr vissza:
public Object pop() throws EmptyStackException { Object obj; if (size == 0) { throw new EmptyStackException(); } obj = objectAt(SIZE - 1); setObjectAt(SIZE - 1, null); size--; return obj;
A pop metdus megnzi, van-e valami a veremben. Ha a verem res (mrete 0), akkor a pop ltal ltrejn egy j EmptyStackException objektumot (a java.util tagja) s eldobja azt. Ezek az objektumok a java.lang.Throwable osztly leszrmazottjai kell, hogy legyenek, a fejezet ksbbi rsze a kivtel osztlyok ltrehozsval foglalkozik. A pop metdus deklarcija magban foglalja a throws kulcsszt. Az EmptyStackException kivtelt a pop metdus nem kapja el, gy a metdusnak a throws kulcsszt kell, hogy hasznlja a deklarcihoz.
18.Kivtelkezels
161. oldal
Error osztly
Ha a mvelet valamilyen okbl kifolylag nem hajthat vgre, sikertelen a vgrehajts, a Java virtulis gp Error-t fog dobni. Egyszer programok nem kapnak el, illetve nem dobnak Error-t.
Exception osztly
A legtbb program elkap s dob objektumokat, melyek az Exception osztlybl szrmaznak. A legtbb ltalunk megrt program elkap s dob kivteleket (jelzi a hibt). Az Exception osztlynak szmos leszrmazottja definilt a Java Platformban, ezek a leszrmazottak jelzik a klnbz tpus kivteleket. Pldul IllegalAccessException jelzi, ha egy klns metdus nem tallhat, a NegativeArraySizeException pedig, ha egy tmb mrett helytelenl adtunk meg (negatv szm). A RuntimeException kivtelek futs kzben generldnak a Java Virtulis gp ltal. Ennek egyik pldja a NullPointerException, mely akkor jn ltre, ha egy metdus megprbl hozzfrni null hivatkozssal valamely objektumhoz.
Az initCause s a Throwable konstruktorok Throwable paramtere egy kivtel, amik okoztk az aktulis kivtelt. A getCause visszaad egy kivtelt, ami okozta az aktulis kivtelt, az initCause pedig visszaadja az aktulis kivtelt. A kvetkez plda megmutatja, hogyan hasznljuk a lncolt kivteleket:
try { ... } catch (IOException e) { throw new SampleException("Other IOException", e); }
Ebben a pldban, amikor az IOException-t kap el a program, akkor egy j SampleException kivtel jn ltre az eredeti okkal egybektve, s a kivtelek lnca feldobdik egy kvetkez, magasabb szint kivtelkezelhz.
162. oldal
Definci: a hvsi verem informcit szolgltat az aktulis szl futsi trtnetrl, az osztlyok s a metdusok neveirl, amik akkor hvdnak meg, amikor a kivtel bekvetkezett. A hvsi verem egy nagyon hasznos hibakeres eszkz. A kvetkez kd megmutatja, hogyan kell a getStackTrace metdust hasznlni a kivtel objektumon:
catch (Exception cause) { StackTraceElement elements[] = cause.getStackTrace(); for (int i = 0; n = elements.length; i < n; i++) { System.err.println(elements[i].getFileName() + ":" + elements[i].getLineNumber() + ">> " + elements[i].getMethodName() + "()"); } }
API naplzs
A kvetkez kdrszlet catch blokkjban naplzsra ltunk pldt. Brmennyire clszernek tnik is az elz plda megkzeltse, rdemes inkbb a naplzs mechanizmust alkalmazni a java.util.logging segtsgvel:
try { Handler handler = new FileHandler("OutFile.log"); Logger.getLogger("").addHandler(handler); } catch (IOException e) { Logger logger = Logger.getLogger("package.name"); StackTraceElement elements[] = e.getStackTrace(); for (int i = 0; n = elements.length; i < n; i++) { logger.log(Level.WARNING, elements[i].getMethodName()); } }
Tegyk fel, hogy rtunk egy lncolt lista osztlyt, amit szeretnnk megosztani nylt forrs programknt. A lncolt lista osztlyunk tbbek kztt a kvetkez metdusokat tmogatja:
18.Kivtelkezels objectAt(int n)
163. oldal
Visszaadja a lista n-dik pozcijban lev objektumot. Kivtelt dob, ha a paramter kisebb, mint 0, vagy nagyobb, mint az aktulis objektumok szma a listban. firstObject() Visszaadja az els objektumot a listban. Kivtelt dob, ha a lista nem tartalmaz objektumot. indexOf(Object o) tnzi a listt egy specilis objektumrt s visszaadja a pozcijt a listban. Kivtelt dob, ha az objektum nincs a listban. A lncolt lista osztly kpes klnbz kivteleket dobni, ugyanakkor lehetsget ad arra is, hogy a felhasznl program el tudja kapni a lncolt lista ltal dobott sszes kivtelt egy kivtelkezelvel. Ha a lncolt listnkat egy csomagban tervezzk megosztani, minden kapcsold kdnak egy kzs csomagban kell lennie. A kvetkez bra illusztrl egy lehetsges osztlyhierarchit a lncolt listk ltal dobhat kivtelekrl:
Szlosztly vlasztsa
Az Exception valamennyi leszrmazott osztlyt lehet a LinkedListException szlosztlynak vlasztani. Azonban knnyen lthat, hogy ezek a leszrmazott osztlyok nem odaillk, mert vagy tl specializltak, vagy nem fggnek ssze a LinkedListException-al. Ezrt a LinkedListException szl osztlynak az Exception-nek kell lennie. A legtbb applet s alkalmazs, amit runk, Exception objektumokat dob. Figyelem: az olvashat kd rdekben egy j gyakorlat, hogy hozzfzzk az Exception szt minden osztly nevhez, amelyik kzvetlenl vagy kzvetve rkldik az Exception osztlybl.
19.Programszlak kezelse
165. oldal
19.Programszlak kezelse
A programok jelents rsze soros vgrehajts. Van kezdetk, egy vgrehajtand rsz s egy befejezs. A program csak bizonyos idszakaszokban fut, hiszen a processzor mr programokat is futtat. A szl (thread) hasonl a soros programhoz. A szlnak is van kezdete, egy vgrehajtand rsze s egy befejezse. A szl is csak bizonyos idszakaszokban fut. De a szl maga nem egy program, a szlat nem lehet nllan futtatni. Inkbb gy tekinthetjk, hogy a program rszeknt fut. A kvetkez bra megmutatja a kapcsolatot.
Definci: A szl egy egyedlll irnyt folyamat a programon bell. Persze nem arra hasznljuk a szlakat, hogy csak egyet alkalmazunk, inkbb tbb szlat futtatva egy idben klnbz feladatokat elvgezve egyetlen programban. A kvetkez kp ezt illusztrlja.
A bngsz programunk is egy plda a tbbszl alkalmazsra. Egy ltalnos bngszben egy oldalon bell egyszerre trtnik egy kp, applet letltse, mozg animci vagy hang lejtszsa, az oldal nyomtatsa a httrben, mikzben egy j oldalt tlt be vagy ppen hrom rendez algoritmus versenyt tekintheti meg. Nha a szlat knnysly processznek nevezik, mert egy teljes programon bell fut, annak lefoglalt erforrsait s a futtat krnyezett hasznlja. Mint irnyt folyamat, a szlnak is kell sajt erforrsokkal rendelkeznie. Rendelkezni kell egy vgrehajt veremmel s a programszmllval. Ebben a krnyezetbe fut a szl kdja. Nhol ezt a krnyezetet a szl fogalom szinonimjnak nevezik. A szl programozs nem egyszer. Ha mgis szlakat kell hasznlni, akkor rdemes a magas-szint szl API-kat hasznlni. Pldakppen, ha a programban egy feladatot tbbszr kell elvgezni, rdemes a java.util.Timer osztlyt alkalmazni. A Timer osztly idztses feladatoknl is hasznos lehet. Erre hamarosan ltunk pldt.
166. oldal
A program egy plda arra, hogyan kell pldnyostani s temezni a szlakat: TimerTask leszrmazott osztly pldnyostsa. A run metdus tartalmazza a futtats sorn vgrehajtand kdot. A pldba ezt az leszrmazott osztly RemindTaskknt neveztk el. Ltrehozzuk a Timer osztly egy pldnyt. Ltrehozunk egy idzt objektumot (new RemindTask()). Betemezzk az idztt. Ez a plda a schedule metdust hasznlja, amelynek paramterei az idzt s ksleltets ezredmsodpercben (5000).
Egy msik lehetsg az temezsre, hogy az indtsi idpontot adjuk meg. Pldakppen a kvetkez kd 23:01-re temezi a vgrehajtst:
Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 1); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); timer = new Timer(); timer.schedule(new RemindTask(), time);
19.Programszlak kezelse
167. oldal
19.1.1
Alapesetben a program addig fut, amg az idzt szl is fut. Ngy lelltsi mdszer kzl vlaszthatunk: A cancel metdust hvjuk meg. Ezt a program brmelyik pontjn megtehetjk, mint a plda run metdusban. Az idzt szlt dmon szll kell tenni a kvetkezkppen: new Timer(true). Ha a programban csak dmon szlak maradnak, akkor a program kilp. Ha befejezdtek az temezsek, el kell tvoltani a Timer objektumhoz tartoz mutatkat. Ezzel a szl is megsznik. A System.exit metdust hvjuk meg, amely lelltja a programot (benne a szlakat is).
A Reminder plda az els mdszert hasznlja, a cancel metdust hvja meg a run metdusbl. A dmon szlknt val ltrehozs a pldnkban nem mkdne, mert a programnak futni kell a szl lefutsa utn is.
19.1.2
Ismtelt futtats
Az AnnoyingBeep program hrom paramteres schedule metdust hasznl, hogy meghatrozza a taszk msodpercenknti indtst. A Timer metdus vltozatai: schedule(TimerTask task, long ksleltets, long gyakorisg) schedule(TimerTask task, Date id, long gyakorisg) scheduleAtFixedRate(TimerTask task, long ksleltets, long gyakorisg) scheduleAtFixedRate(TimerTask task, Date kezdetiId, long gyakorisg)
A schedule metdust akkor hasznljuk, ha a tbbszrsen futtatott taszk ismtlsi ideje szmt, a scheduleAtFixedRate metdust, ha az ismtlsek idben ktdnek egy pontos idhz. A pldban is a schedule metdust alkalmaztuk, amitl 1 msodperces intervallumokban spol a gp. Ha valamelyik spsz ksik, akkor a kvetkezk is kslekednek. Ha gy dntnk, hogy a program 3 msodperc mlva kilp az els spsz utn ami azt is eredmnyezheti, hogy a kt spsz kisebb idkzzel szlal meg, ha kslekeds lp fel akkor a scheduleAtFixedRate metdust hasznljuk.
19.2.1
Az els lps a szlak testreszabsnl, hogy Thread osztly leszrmazottjt ltrehozzuk, s az res run metdust fellrjuk, hogy csinljon is valamit. Nzzk meg a SimpleThread osztlyt, amely ezt teszi:
public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); }
19.Programszlak kezelse
public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("KSZ! " + getName()); }
169. oldal
A SimpleThread osztly els metdusa egy konstruktor, amely paramterknt egy String-et fogad. A konstruktor meghvja az sosztly konstruktort, ami azrt rdekes szmunkra, mert az belltja a szl nevt. Ezt a nevet hasznljuk a ksbbi programban a szl felhasznli azonostsra. A nevet ksbb a getName metdussal tudjuk lekrdezni. A SimpleThread osztly kvetkez metdusa a run. Itt trtnik a Thread rdemi mkdse. Ebben az esetben egy tizes for ciklust tartalmaz. Minden ciklusban kirja az iterci szmt, a Thread nevt, s utna altatsra kerl vletlenszeren 1 msodperces hatron bell. Ha vgzett, a KSZ! feliratot rja ki a szl nevvel egytt. Ennyi a SimpleThread osztly. Hasznljuk fel ezt a TwoThreadsTest-ben. A TwoThreadsTest osztly main metdusba kt SimpleThread szlat hozunk ltre: Jamaica s Fuji. (Ha valaki nem tudn eldnteni hova menjen nyaralni, akkor hasznlja ezt a programot.)
public class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); } }
A main metdus azonnal mindkt szlat ltrehozza a start metdus meghvsval, amely a run metdust hvja meg. Fordts s futtats utn kibontakozik az ti cl. A kimenet hasonl kell, hogy legyen:
170. oldal
Figyeljk meg, hogy a szlak kimenete mennyire fggetlen egymstl. Ennek az az oka, hogy a SimpleThread szlak egyidejleg futnak. Mindkt run metdus fut, s mindkettnek van sajt kimenete ugyanakkor. Ha a ciklus befejezdik, a szlak lellnak s meghalnak.
19.2.2
A kvetkez Clock applet a jelenlegi idt mutatja, s azt msodpercenknt frissti. A frissts lland, mivel az ra kijelzse egy sajt szlon fut. Az applet ms mdszert hasznl, mint a SimpleThread. Itt ugyanis a szlosztly csak az Applet lehet, de gy az egyszeres rklds miatt a Thread mr nem lehet szl. Ezrt a plda Thread leszrmazott ltrehozsa helyett egy Runnable interfszt implementl, ezrt a run metdust ebben definilja. A Clock ltrehoz egy szlat, amelynek a frissts a clja.
import import import import java.awt.*; java.util.*; java.applet.*; java.text.*;
public class Clock extends java.applet.Applet implements Runnable { private volatile Thread clockThread = null; DateFormat formatter; // Formats the date displayed String lastdate; // String to hold date displayed Date currentDate; // Used to get date to display Color numberColor; // Color of numbers Font clockFaceFont; Locale locale; public void init() { setBackground(Color.white); numberColor = Color.red; locale = Locale.getDefault(); formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM, locale); currentDate = new Date(); lastdate = formatter.format(currentDate); clockFaceFont = new Font("Sans-Serif", Font.PLAIN, 14); resize(275,25); } public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } }
19.Programszlak kezelse
public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){ } } }
171. oldal
public void paint(Graphics g) { String today; currentDate = new Date(); formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM, locale); today = formatter.format(currentDate); g.setFont(clockFaceFont); // Erase and redraw g.setColor(getBackground()); g.drawString(lastdate, 0, 12); g.setColor(numberColor); g.drawString(today, 0, 12); lastdate = today; currentDate=null;
A Clock applet run metdusa addig nem lp ki a ciklusbl, amg a bngsz le nem lltja. Minden ciklusban az ra kimenete jrarajzoldik. A paint metdus lekrdezi az idt, formzza s kijelzi azt.
Ahhoz, hogy egy bngszben futhasson a Clock osztlynak az Applet osztly leszrmazottjnak kell lennie. Tovbb a Clock applet folyamatos kijelzse miatt egy szlra van szksge, hogy ne a processzt vegye t, amiben fut. (Nhny bngsz figyelhet arra, hogy az appletek sajt szlat kapjanak, elkerlend, hogy a hibs appletek elvegyk a bngsz szlt. De erre nem pthetnk egy applet rsnl. Az ltalunk rt appletnek tudnia kell a sajt szl ltrehozst, ha olyan munkt vgez.) De mivel a Java nyelv nem engedlyezi a tbb osztlyokon t val rkldst, a Clock nem lehet egyszerre a Thread s az Applet osztly leszrmazottja. gy a Clock osztlynak egy Runnable interfszen keresztl kell a szlak viselkedst felvennie.
172. oldal
19.3.1
Programszl ltrehozsa
Az alkalmazs, melyben egy szl fut, meghvja a szl start metdust, amikor a felhasznl a programot elindtja. A Clock osztly ltrehozza a clockThread szlat a start metdusban, ahogy a lenti programkd bemutatja:
public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } }
Miutn a kiemelt utasts vgrehajtdik, a clockThread az j szl (New Thread) llapotban van. Egy szl ebben az llapotban csupn egy res szl, semmifle rendszererforrs nincs hozzrendelve. Ebben az llapotban csak elindthat a szl. A start metduson kvl brmilyen metdus meghvsa rtelmetlen, s IllegalThreadStateException kivtelt eredmnyez. (Alaprtelmezetten a rendszer mindig ezt a hibazenetet dobja, ha egy olyan metdus kerl meghvsra, amelyik a szl pillanatnyi llapotban nem engedlyezett.) rdemes megjegyezni, hogy a Clock tpus pldny az els paramter a szl konstruktorban. Ez a paramter meg kell, hogy valstsa a Runnable interfszt, csak gy lehet a konstruktor paramtere. A Clock szl a run metdust a Runnable interfsztl rkli. A konstruktor msodik paramtere csupn a szl neve.
19.3.2
Programszl elindtsa
19.Programszlak kezelse
173. oldal
A start metdus ltrehozza a szksges rendszererforrsokat a szl futtatshoz, elkszti a szlat a futshoz, s meghvja a szl start metdust. A clockThread run metdusa a Clock osztlyban van definilva. Miutn a start metdus visszatr, a szl fut. Mgis, ennl azrt kicsit komplexebb a dolog. Ahogy az elz bra is mutatja, egy elindtott szl a futtathat llapotba kerl. Sok szmtgp csak egy processzorral rendelkezik, gy lehetetlen, hogy minden futsi llapotban lv szl egyszerre fusson. Ezrt a Java futtatrendszernek implementlnia kell egy temezsi smt, ami elosztja a processzor erforrsait az sszes fut szl kztt. Szval egy bizonyos idpontban, egy fut szl valsznleg vr, hogy kerljn sorra a CPU temezsben. Mg egyszer a Clock run metdusa:
public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { // The VM doesn't want us to sleep anymore, // so get back to work } } }
A Clock run metdusa addig lpked a ciklusban, amg a clockThread == myThread felttel nem lesz igaz. A cikluson bell a szl jra kirajzolja az appletet, majd utastja a szlat, hogy kerljn alv llapotba 1 msodpercre. A repaint metdus vgs soron meghvja a paint metdust, ami az aktulis frisstseket vgzi a program megjelentsi felletn. A Clock paint metdusa eltrolja az aktulis rendszeridt, formzza, majd megjelenti:
public void paint(Graphics g) { //get the time and convert it to a date Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); //format it and display it DateFormat dateFormatter = DateFormat.getTimeInstance(); g.drawString(dateFormatter.format(date), 5, 10); }
19.3.3
Egy szl akkor vlik nem futtathatv, ha a lenti esemnyek kzl brmelyik is bekvetkezik: Meghvsra kerl a sleep metdusa. A szl meghvja a wait metdust, hogy az vrjon egy bizonyos felttel teljeslsre. A szl blokkolt egy I/O mvelet miatt.
A clockThread a Clock szlon bell akkor kerl nem futtathat llapotba, mikor a futs metdus meghvja a sleep-et a jelenlegi szlban:
174. oldal
public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { // A VM nem akarja, hogy tovbb aludjunk, // szval irny vissza dolgozni } } }
Az alatt a msodperc alatt, amg a clockThread alv llapotban van, a szl nem fut, mg akkor sem fog, ha a processzor erforrsai elrhetv vlnak. Miutn letelik az egy msodperc, a szl jra futtathatv vlik; ha a processzor erforrsai elrhetv vlnak, a szl jra futni kezd. Minden egyes nem futtathat llapotba kerlskor, egy specifikus s megklnbztethet exit metdus trti vissza a szlat a futtathat llapotba. Egy exit hvs utn csak a megfelel felttelek teljeslse esetn fog ismt futni. Pldul: miutn egy szl alv llapotba lett helyezve, a meghatrozott ezredmsodpercek lejrta utn jbl futtathat llapotba kerl. A kvetkez felsorols lerja a nem futtathat llapot kilpsi feltteleit: Ha a szl alv llapotba lett helyezve, a meghatrozott idnek le kell telnie. Ha egy szl egy felttelre vr, akkor egy msik objektumnak kell rtestenie a vrakoz szlat a felttel teljeslsrl a notify vagy notifyAll metdus meghvsval. Ha egy szl blokkolva volt egy I/O mvelet miatt, az I/O mveletnek be kell fejezdnie.
A szl a run metdusban termszetesen hal meg mikor a ciklus befejezdik s a run metdus kilp. Nzzk meg, hogyan hajtja vgre a Clock szl a sajt hallt. Nzzk meg jra a Clock run metdust:
19.Programszlak kezelse
public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { //the VM doesn't want us to sleep anymore, //so get back to work } } }
175. oldal
A kilpsi felttel ebben a run metdusban ugyanaz a kilpsi felttele, mint a while ciklusnak, mert a ciklus utn nincs kd:
while (clockThread == myThread) {
E felttel jelzi, hogy a ciklus kilp, ha a jelenleg futsban lv szl nem egyezik a clockThread-el. Mikor lesz ez a helyzet? Akkor, amikor a felhasznl elhagyja az oldalt, az alkalmazs, melyben a szl fut, meghvja a szl stop metdust. Ez a metdus ezutn belltja a clockThread-et null rtkre, gy utastva a f ciklust, hogy szaktsa meg a futs metdust:
public void stop() { // applets' stop method clockThread = null; }
19.3.5
Az 5.0-s verziban kerlt bevezetsre a Thread.getState metdus. Mikor ez kerl meghvsra, az albbi Thread.State rtkek valamelyike tr vissza: NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED
A Thread osztlyhoz tartoz API tartalmazza az isAlive metdust is. Az isAlive metdus igaz visszatrsi rtket generl, ha a szlat elindtottk, de mg nem lett lelltva. Ha az isAlive visszatrsi rtke hamis, akkor tudhatjuk, hogy a szl vagy j szl (NEW), vagy halott llapotban van (TERMINATED). Ha a visszatrsi rtk igaz, akkor viszont a szl vagy futtathat (RUNNABLE), vagy nem futtathat llapotban van. Az 5.0-s verzit megelzen nem lehetett klnbsget tenni az j szl vagy a halott szlak kztt. Ugyancsak nem lehetett megklnbztetni a futtathat, vagy nem futtathat llapotban lv szltl.
176. oldal
lyek bizonyos idkznknt nkntesen felhagynak a processzor hasznlatval, ezzel megadva a lehetsget minden szlnak a futsra. Egy szl nkntesen abbahagyhatja a CPU hasznlatt a yield metdus meghvsval.
Mi annak a metdusnak a neve, amellyel a kln programszl futst kezdemnyezni tudjuk? init start run resume sleep
Mi annak a metdusnak a neve, amellyel a programszl futst le tudjuk lltani? (Minden helyes vlaszt jelljn meg!) sleep stop yield wait notify notifyAll synchronized
19.Programszlak kezelse
177. oldal
Fordtsi hiba, mert a run metdus nincs definilva a Background osztlyban Futsi hiba, mert a run metdus nincs definilva a Background osztlyban A program lefut, s 0-tl 9-ig r ki szmokat A program lefut, de nincs kimenete
178. oldal
20.Fjlkezels
A legtbb programnak szksge van arra, hogy kls forrsbl olvasson adatokat, vagy kls clba rja a mkdse (rsz)eredmnyeit. A forrs s a cl sokfle lehet: konzol, httrtr, msik program, vagy egyb specilis eszkzk. Az adatok is klnbzk lehetnek: szmok, szvegek, vagy akr tetszleges objektumok. Ez a fejezet bemutatja, hogy hogyan lehet Java nyelven kezelni az adatllomnyainkat.
20.1. Adatfolyamok
Informci kinyershez a program megnyit egy adatfolyamot az informciforrshoz (fjl, memria, socket), s sorban kiolvassa az informcit, amint az brn ltszik:
Hasonlkppen, egy program kls clba is kldheti az informcikat adatfolyam megnyitsval, s informcikat rhat ki sorban, mint itt:
Nem szmt, mekkora adat jn be, vagy megy ki, s nem szmt a tpusa, az algoritmus sorban olvassa s rja, a kvetkezkz hasonlan: Olvass
adatfolyam megnyitsa amg van jabb informci olvass adatfolyam bezrsa
rs
adatfolyam megnyitsa amg van jabb informci rs adatfolyam bezrsa
A java.io csomag tartalmazza azon osztlyokat, melyek lehetv teszik az rst s olvasst. Az osztlyok hasznlathoz importlni kell a java.io csomagot. Az adatfolyam osztlyok kt hierarchira oszthatk az adattpusuk alapjn (karakter vagy bjt):
20.Fjlkezels
179. oldal
Karakter folyamok
Reader s Writer a java.io absztrakt sosztlyai. 16 bites karakterekkel val mveleteket teszik lehetv. A Reader s Writer leszrmazott osztlyai specilis mveleteket vgeznek, s kt kln kategrira oszthatk: az adat olvass s rs (szrkvel jelezve) s feldolgozsok vgrehajtsa (fehrek). Az utbbiakat szr folyamoknak is nevezzk. A Reader s Writer osztlyok osztlyhierarchijt mutatja az bra.
A legtbb programnak szksge van a Reader s Writer osztlyokra szveges informcik olvasshoz s rshoz. Ezek brmilyen karaktert kpes lekezelni Unicode karakterknt.
Binris folyamok
A 8-bites bjt rshoz s olvasshoz a programnak hasznlnia kell a binris folyamokat, melyek az InputStream s OutputStream leszrmazottai. Ezek a folyamok jellemzen binris adatok olvassra s rsra alkalmasak, mint egy kp vagy hang. A bjt folyam kt osztlya, ObjectInputStream s ObjectOutputStream hasznlhat objektumok soros folyamon keresztli kezelshez.
180. oldal
Az InputStream s OutputStream osztlyok a Reader s Writer osztlyokhoz hasonlam kt kategrira oszthatk, a kvetkez osztlyhierarchia alapjn: adatkezel folyamok (szrke) s feldolgoz vagy ms nven szr folyamok (fehr).
Az I/O szlosztlyok
Reader s InputStream azonos API-kat hatroznak meg, de klnbz adattpusra. A Reader metdusai karakterek s karaktertmbk olvassra alkalmasak:
int read() int read(char cbuf[]) int read(char cbuf[], int offset, int length)
A Reader s InputStream is megvalstja az adatfolyamon belli llapot jellst, ugrlst, s az aktulis pozci visszalltst. A Writer s OutputStream hasonl szolgltatsokkal rendelkeznek. A Writer karakterek, s karaktertmbk rst valstja meg:
int write(int c) int write(char cbuf[]) int write(char cbuf[], int offset, int length)
Mind a ngy osztly esetn igaz, hogy automatikusan megnylik az adatfolyam, ha ltre van hozva az objektum. Minden adatfolyam bezrhat a close meghvsval. A szemt-
20.Fjlkezels
181. oldal
gyjt is bezrja, ha mr nincs r hivatkozs, de clszer inkbb direkt mdon meghvni a close metdust.
Megjegyezs: A program ktelessge, hogy minden erforrst csak a tnylegesen szksges ideig foglaljon le. ppen ezrt az llomny megnyitst olyan ksn kell megtenni, amikor csak lehet, s ugyanilyen hamar be is kell zrni.
StringBufferInputStream
Cs
Fjl
Tbb bemenet adatfolyamainak szszefzse egy bemeneti adatfolyamba. Ob- Objektumok soros szervezs trolshoz s visszalltshoz. Primitv adattpusok rsa s olvassa gpfggetlen formtumban. Nyomon kvethet a sorok szma olvasskor. A bemeneti adatfolyamok egy vissza-
182. oldal
Java programozs (1.3. verzi) tehet pufferbe kerlnek. Az adatok olvassakor nha hasznos a kvetkez nhny bjt vagy karakter ismerete a kvetkez lps eldntshez. Nyomtatsi metdusokat tartalmaz. Az adatfolyamok tartalmnak kiratsra hasznlhat.
PushbackInputStream
Kinyomtats
PrintWriter PrintStream
Pufferels
BufferedReader BufferedWriter
Olvasskor s rskor az adatok puffereldnek, ezltal cskkentve a forrs adat elrseinek szmt. A pufferelt BufferedInputStream Buf- adatfolyamok hatkonyabbak, mint a feredOutputStream nem pufferelt adatfolyamok, s gyakran hasznlhatk ms adatfolyamokkal is. FilterReader FilterWriter FilterInputStream FilterOutputStream Ezek az absztrakt osztlyok a szr adatfolyamok vzt adjk meg, milyen szrs hasznlhat rskor vagy olvasskor. Az olvas s r pros hidat kpez a bjt s a karakterfolyamok kztt. Az InputStreamReader bjtokat olvas egy InputStream-bl s karakterbe konvertlja, az alaprtelmezett karakterkdolst vagy egy megnevezett karakterkdolst hasznlva. Az OutputStreamWriter karaktereket konvertl bjtba, az alaprtelmezett karakterkdolst vagy egy megnevezett karakterkdolst hasznlva s a bjtokat egy OutputStream-be rja.
Szrs
InputStreamReader OutputStreamWriter
20.1.1
A fjl adatfolyamok taln a legknnyebben megrthet adatfolyamok. A fjl adatfolyamok (FileReader, FileWriter, FileInputStream, s FileOutputStream) a natv fjlrendszer fjljait olvassk, vagy rjk. Ltrehozhatunk fjl adatfolyamot fjlnv String-bl, File objektummal, vagy FileDescriptor objektummal. A kvetkez Copy program FileReader s FileWriter segtsgvel az input.txt tartalmt trja (tmsolja) az ouput.txt fjlba:
import java.io.*; public class Copy { public static void main(String[] args) throws IOException{ File inputFile = new File("input.txt"); File outputFile = new File("output.txt");
20.Fjlkezels
FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close();
183. oldal
} }
A program nagyon egyszer. A FileReader megnyitja a farrago.txt fjlt, a FileWriter pedig az outagain.txt fjlt. A program az in objektummal beolvas minden karaktert a bemeneten a bemeneti fjlbl, s az out objektummal kirja a karaktereket. Ha a bemenet elfogyott (-1), a program bezrja az olvast s az rt is.
Megjegyzs: rdemes megfigyelni, a read s write metdusok nem char, hanem int tpussal dolgoznak. Ennek mindssze az az oka, hogy egy specilis, a char megengedett rtktartomnyn kvli visszatrsi rtket (a -1-et) is kell nyjtani abban az esetben, ha nincs tbb olvashat karakter, gy a char nem lenne alkalmazhat.
A kd ltrehoz egy File objektumot, ami a fjl logikai lersra szolgl. A File segdosztlyt a java.io tartalmazza. A Copy program ezt az objektumot hasznlja a FileReader felptshez. Azonban a program az inputFile-t akkor is hasznlhatja, ha informcit szeretnnk szerezni a fjl egszrl (pl. olvashat-e, mekkora a mrete stb). A program futsa utn ugyanannak kell szerepelnie az input.txt s az output.txt fjlban is. Ne feledjk, hogy a FileReader s a FileWriter 16-bites karaktert olvas s r. Azonban, a legtbb natv fjlrendszer 8-biten alapszik Az adatfolyamok kdoljk a karaktereket, az alaprtelmezett karakterkdolsi sma alapjn. A karakterkdols megkaphat a System.getProperty("file.encoding") hasznlatval. j alaprtelmezett kdols megadshoz ltre kell hozni egy OutputStreamWriter vagy egy FileOutputStream objektumot, s megadni a kdolst.
A java.io csomag csak egy szrmaztatott osztlyt tartalmazza a FilterReader-nek, ez nem ms, mint a PushbackReader. A kvetkez fejezet bemutatja egy pldn szemlltetve, hogyan hasznljuk a szr adatfolyamokat a DataInputStream s a DataOutStream hasznlatval. Ugyancsak trgyalja, hogyan hozhatunk ltre szrmaztatott osztlyokat a FilterInputStream s FilterOutputStream-bl, melyek segtsgvel sajt szr adatfolyamunkat valsthatjuk meg.
A kvetkezkben egy pldn szemlltetjk a DataInputStream s DataOutputStream hasznlatt. Ezek olyan szrk melyek kpesek rni/olvasni elemi adattpusokat. Elfordul, hogy a feldolgozs fggetlen a kezelt adat formtumtl, de nha szorosan sszefgg az illet adatokkal vagy annak formtumaival, gymint adatok rsa, olvassa sorokbl vagy cellkbl.
DataOutputStream-et, mint ahogyan ms kimeneti adatfolyamokat, csatolni kell egy msik OutputStream-hez. Ebben az esetben a FileOutputStream-hez csatoltuk. Plda:
DataOutputStream out = new DataOutputStream( new FileOutputStream("invoice1.txt"));
A DataIODemo a DataOutputStream specilis write metdusait hasznlja rsra, amennyiben az megfelel tpus.
20.Fjlkezels
for (int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeChar('\t'); out.writeInt(units[i]); out.writeChar('\t'); out.writeChars(descs[i]); out.writeChar('\n'); } out.close();
185. oldal
Mihelyst beolvasta az adatokat, a DataIODemo megjelenti az sszegzst, a rendelt s az sszes mennyisget, majd bezrul.
Megjegyzs: a DataIODemo ltal hasznlt ciklus a DataInputStream-bl olvassa az adatokat:
A read metdus null rtkkel tr vissza, mely a fjl vgt jelenti. Szmos alkalommal azonban ezt nem tehetjk meg, a szablytalanul megadott rtkek esetn hibajelzst kapunk. Tegyk fel, hogy -1 rtket szeretnnk ugyanerre a clra felhasznlni. Ezt nem tehetjk meg, ugyanis a -1 nem szablyos rtk, kiolvassa a readDouble vagy readInt hasznlatval trtnik. Teht DataInputStream-ek esetn nem kapunk EOFException kivtelt. A program futsa a kvetkez kimenetet eredmnyezi:
You've ordered 12 units of Java T-shirt at $19.99 You've ordered 8 units of Java Mug at $9.99 You've ordered 13 units of Duke Juggling Dolls at $15.99 You've ordered 29 units of Java Pin at $3.99 You've ordered 50 units of Java Key Chain at $4.99 For a TOTAL of: $892.8800000000001
186. oldal
20.2.Objektum szerializci
A java.io kt adatfolyama -az ObjectInputStream s az ObjectOutputStream- abban ms az tlagos bjtfolyamoktl, hogy objektumokat tudnak rni s olvasni. Az objektumok rsnak az alap felttele, hogy egy olyan szerializlt formra hozzuk az objektumot, ami elegend adatot tartalmaz a ksbbi visszaalaktshoz. Ezrt hvjuk az objektumok rst s olvasst objektum szerializcinak. Objektumokat a kvetkez kt mdon lehet szerializlni: Tvoli eljrshvs (Remote Method Invocation, RMI) Kliens s szerver kztti objektumtvitel esetn Knnysly perzisztencia (Lightweight persistence) Egy objektum archivlsa ksbbi hasznlatra
Az ObjectOutputStream konstruktort egy msik adatfolyamra kell meghvni. Az elz pldban az ObjectOutputStream konstruktora egy FileOutputStream-re hvdik, gy egy 'theTime' nev fjlba szerializlja az objektumot. Ezek utn egy String (Today) s egy Date objektum rdik az adatfolyamra az ObjectOutputStream writeObject nev metdusval. A writeObject metdus szerializlja az adott objektumot, rekurzvan tmenti a ms objektumokra val hivatkozsait, gy megtartja az objektumok kztti kapcsolatot. Az ObjectOutputStream implementlja a DataOutput interfszt, ami primitv adattpusok rsra val metdusokat tartalmaz (writeInt, writeFloat, writeUTF). Ezeket a metdusokat hasznljuk primitv adattpusok ObjectOutputStream-re val rshoz. A writeObject metdus NotSerializableException-t dob, ha a megadott objektum nem szerializlhat. Egy objektum csak akkor szerializlhat, ha implementlja a Serializable interfszt.
Az ObjectInputStream olvassa
A kvetkez pldaprogram kiolvassa a theTime fjlba elzleg kirt String s Date objektumokat:
FileInputStream in = new FileInputStream("theTime"); ObjectInputStream s = new ObjectInputStream(in); String today = (String)s.readObject(); Date date = (Date)s.readObject();
20.Fjlkezels
187. oldal
Az ObjectOutputStream-hez hasonlan az ObjectInputStream konstruktort is egy msik adatfolyamra kell hvni. Mivel egy fjlba rtuk az objektumokat, itt is egy FileInputStream-re kell hvni az ObjectInputStream-et. Az olvasst az ObjectInputStream readObject metdusa vgzi. Az objektumokat mindenkppen abban a sorrendben kell kiolvasni, ahogy az adatfolyamra lettek rva. A readObject metdus deszerializlja a soron kvetkez objektumot. Rekurzvan vizsglja a hivatkozsokat, hogy az sszes hivatkozott objektumot is deszerializlja, gy megtartva az objektumok kztti kapcsolatot. Az ObjectInputStream adatfolyam implementlja a DataInput interfszt, ami primitv adattpusokat olvas metdusokat tartalmaz. A DataInput metdusai a DataOutput metdusainak olvas megfeleli (readInt, readFloat, readUTF...).
A Serializable egy res interfsz (vagyis nincs egyetlen tagja sem), csak a szerializlhat osztlyok elklntsre val. Az osztly pldnyainak a szerializlst az ObjectOutputStream osztly defaultWriteObject nev metdusa vgzi. A deszerializci az ObjectInputStream osztly defaultReadObject metdusval vgezhet el. A legtbb objektumhoz ez a mdszer elg is. Nhny esetben viszont lass lehet, s az osztlynak is szksge lehet a szerializci feletti hatrozottabb vezrlsre.
A szerializci testreszabsa
Az objektum szerializci testreszabshoz kt metdus fellrsra van szksgnk: a writeObject metdus (rsra) s a readObject (olvassra vagy adatfrisstsre). A writeObject deklarlsa:
private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); // testreszabott szerializl kd }
Mindkt metdust pontosan a bemutatott mdon kell deklarlni. A writeObject s a readObject metdusok csak az adott osztly szerializlsrt felelsek, a szl osztlyok esetleges szerializlsa automatikus. Ha egy osztlynak a szlosztlyaival teljesen sszhangban kell lennie a szerializcihoz, akkor az Externalizable interfszt kell implementlni.
188. oldal
Egy Externalizable osztlynl a kvetkezket kell szem eltt tartani: implementlnia kell a java.io.Externalizable interfszt. implementlnia kell a writeExternal metdust az objektum llapotnak az elmentshez. implementlnia kell a readExternal metdust a writeExternal ltal az adatfolyamra rt tartalom visszalltshoz. kls adatformtum rsrt s olvassrt kizrlag a writeExternal s a readExternal metdusok felelsek.
A writeExternal s a readExternal metdusok publikusak, gy lehetsget nyjtanak arra, hogy egy kliens az objektum metdusai nlkl is tudja olvasni/rni az objektum adatait, ezrt csak kevsb biztonsg-ignyes esetekben alkalmazhatak.
20.Fjlkezels
189. oldal
hozzfrs tiltsra van szksg, egy NotSerializableException dobsa elg, hogy megtagadjuk a hozzfrst.
Feltve, hogy egy meghatrozott fjlt akarunk kicsomagolni a ZIP-bl, soros hozzfrs esetn a kvetkezket kell tennnk: Megnyitjuk a ZIP fjlt Vgigkeressk a ZIP fjlt a keresett llomnyrt Kicsomagoljuk az llomnyt Bezrjuk a ZIP-et
Ezt az algoritmust hasznlva, tlagban legalbb a ZIP llomny felt vgig kell olvasni a keresett llomnyrt. Kitmrthetjk ugyanezt a fjlt a ZIP-bl sokkal hatkonyabban, ha a kzvetlen elrs fjl seek, azaz keressi funkcijt hasznljuk a kvetkez lpsek szerint: Megnyitjuk a ZIP fjlt Megkeressk a dir bejegyzst s azon bell a kitmrtend fjl helyt Megkeressk (visszafel) a fjl pozcijt a ZIP-en bell Kicsomagoljuk az llomnyt Bezrjuk a ZIP-et
Ez a mdszer sokkal hatkonyabb, mert csak a dir bejegyzst s kicsomagoland fjlt kell beolvasni. A java.io csomagban tallhat RandomAccessFile osztly implementlja kzvetlen elrs fjlokat.
190. oldal
Fontos tovbbi szolgltats, hogy ezen kvl az aktulis llomny pozci kzvetlenl is manipullhat a kvetkez metdusokkal: int skipBytes(int) void seek(long) long getFilePointer() elre mozgatja az aktulis pozcit a megadott pozcira mozgatja az aktulis pozcit lekrdezi a pillanatnyi pozcit
File
Egy fjlt kpvisel a natv fjlrendszerben. Ltrehozhatunk a File objektumot egy llomnyhoz a natv fjlrendszerben, s adatokat krdezhetnk le az llomnyrl. Pldul a teljes elrsi tjt.
FileDescriptor
Egy fjlkezelt valst meg nyitott llomnyok s portok esetn. Nem sokszor hasznlt.
20.Fjlkezels
191. oldal
StreamTokenizer
Adatfolyam tartalmt trdeli rszekre (tokenekre). A tokenek a legkisebb egysgek (szavak, szimblumok), melyeket a szvegfelismer algoritmusok kpesek felismerni. A StreamTokenizer objektumok brmely szveges fjl elemzsre hasznlhatk. Pldul hasznlhat a forrsllomnyoktl a vltoznevek, opertorok, illetve HTML fjlokbl HTML tagok kigyjtsre. (A StringTokenizer-hez hasonl feladatot lt el.)
FilenameFilter
A File osztly list metdusa hasznlja, hogy mely llomnyok vannak egy listzand knyvtrban. A FilenameFilter hasznlhat az egyszer kifejezs stlus llomny keres mintk implementlsra, mint pldul *.doc, vagy akr sokkal bonyolultabb szrsekre is. Tallhatak mg egyb input osztlyok a java.util.zip csomagban:
CheckedInputStream s CheckedOutputStream
Egy ki- s bementi adatfolyam pr, mely egy ellenrz sszeget szmt az adatok rsakor s olvassakor.
DeflaterOutputStream s InflaterInputStream
Betmrti s kitmrti az adatokat rskor s olvasskor.
GZIPInputStream s GZIPOutputStream
GZIP formban tmrtett adatokat r s olvas.
ZipInputStream s ZipOutputStream
ZIP formban tmrtett adatokat r s olvas.
20.5.Ellenrz krdsek
Mi az r karaktercsatornk absztrakt se? Mi az olvas karaktercsatornk absztrakt se? Mi az r bjtcsatornk absztrakt se? Mi az olvas bjtcsatornk absztrakt se? Melyik metdus hasznlhat az sszes olvas csatorna esetn? Melyik metdus hasznlhat az sszes r csatorna esetn? Mondjon pldt memria-csatornra! rjon pldt a File osztly szolgltatsaira! Mik a szr folyamok?
A vletlen elrs llomny segtsgvel egy fjlnak brmelyik bjtja mdosthat. Az objektumfolyamra rhat primitv adat is. Az objektumfolyamra rt objektumnak implementlnia kell a Serializable interfszt. A pufferez folyamhoz mindig csatolni kell egy msik folyamatot.
A kvetkezk kzl melyik hoz ltre InputStreamReader objektumot? (Minden helyes vlaszt jelljn meg!) new InputStreamReader(new FileInputStream("data")); new InputStreamReader(new FileReader("data")); new InputStreamReader(new BufferedReader("data")); new InputStreamReader("data"); new InputStreamReader(System.in);
A kvetkezk kzl melyik korrekt? RandomAccessFile("data", "r"); RandomAccessFile("r", "data"); RandomAccessFile("data", "read"); RandomAccessFile("read", "data");
Melyikre nem kpes a File osztly? Aktulis knyvtr belltsa Szl knyvtr nevnek ellltsa llomny trlse llomny(ok) keresse
21.Gyjtemnyek
193. oldal
21.Gyjtemnyek
A gyjtemnyek (vagy ms nven trolk, kontnerek, kollekcik) olyan tpuskonstrukcis eszkzk, melynek clja egy vagy tbb tpusba tartoz objektumok memriban trtn sszefoglal jelleg trolsa, manipullsa s lekrdezse.
A JCF-hez hasonl legismertebb megolds a C++ nyelv szabvnyos minta-knyvtr (Standard Template Library, STL).
21.1.1
194. oldal
21.2. Interfszek
A gyjtemny interfszek klnbz tpus gyjtemnyek lerst teszik lehetv, amint az albbi bra mutatja. Ezek az interfszek lehetv teszik a klnbz gyjtemny-reprezentcik egysges kezelst. A gyjtemny interfszek a Gyjtemny keretrendszer alapjainak tekinthetk.
Ahogy az brn lthat, a gyjtemny interfszek hierarchit alkotnak: a Set egy specializlt fajtja a Collection-nek, a SortedSet specializlt fajtja a Set-nek, s gy tovbb. A hierarchia kt egymstl fggetlen fbl ll: a Map nem Collection leszrmazott. Vegyk figyelembe, hogy a gyjtemny interfszek (ltalnos, generikus) tpus paramterekkel dolgoznak. Pldul a Collection interfsz deklarcija:
public interface Collection<E> ...
Az <E> szintaxis azt jelenti, hogy az interfsz ltalnos (generikus) tpussal mkdik. Amikor deklarlunk egy Collection-t, meg tudjuk hatrozni, hogy milyen tpus objektumot tartalmaz a gyjtemny. A tpus paramter a fordtprogram szmra lehetv teszi, hogy csak az adott tpus objektumot engedje belerakni a gyjtemnybe, gy cskkenti a futsidej hibk szmt. Mikor megrtjk, hogyan hasznljuk ezeket az interfszeket, akkor megrtettk a Gyjtemny keretrendszer lnyegt. Ez a fejezet be fogja mutatni az ltalnos irnyelveket, hogy hogyan lehet hatkonyan hasznlni ezeket az interfszeket. Tovbb irnyt ad, hogy mikor melyik interfszt hasznljuk. Minden egyes interfszhez tanulni fogunk programozsi trkkket, hogy segtsen megoldani a legtbb ksbbi problmt.
21.Gyjtemnyek
195. oldal
Hogy megrizze a gyjtemny interfszek kezelhetsgt, a Java platform nem klnti el az interfszeket a tartalom mdosthatsga szempontjbl. (Bizonyos esetekben a gyjtemnyek lehetnek llandk, fix mretek vagy ppen csak bvthetk.) A mdostsi lehetsgek az egyes interfszekben szabadon vlaszthatk: az adott implementci vlaszthatja azt is, hogy nem tmogatja az sszes mveletet. Ha egy nem tmogatott mvelet kerl meghvsra, az adott gyjtemny implementci az UnsupportedOperationException kivtelt dobja. A Java platform minden ltalnos cl implementcija tmogatja az sszes opcionlis mveletet is.
21.2.1
A gyjtemny interfszek
Collection
A gyjtemny hierarchia gykere. A Collection objektumok csoportjt reprezentlja, amiket elemeknek hvjuk. A gyjtemny interfsz a legkisebb kzs nevez a gyjtemny implementcik kztt, s akkor rdemes ezt vlasztani, ha a lehet legnagyobb rugalmassgra van szksg. A gyjtemnyek nhny tpusa engedlyezi az elemek dupliklst, a tbbi pedig nem. A gyjtemnyek nhny tpusa rendezett, a tbbi nem rendezett. A Java platform nem biztost kzvetlen implementcit ehhez az interfszhez, ehelyett a sokkal specifikusabb al-interfszeket implementlja.
Set
Ez a gyjtemny nem tartalmazhat dupliklt elemeket. Ezt az interfszt halmazok trolsra szoktk hasznlni, mint pldul a fut processzek halmaza.
List
A List rendezettsget biztost gyjtemny, nha szekvencinak is hvjk. A listk tartalmazhatnak dupliklt elemeket. A lista felhasznlja egsz index segtsgvel hozz tud frni az elemekhez (hasonlan a tmbk indexelshez), valamint lehetsget kap a lista egyszer bejrshoz.
Queue
Tipikusan ez a gyjtemny szokta trolni a feldolgozsra vr elemeket. A Collection alapmveletein fell lehetsget ad tovbbi beszrsi, kivteli, s megtekintsi mveletekre. Legtbbszr, de nem szksgkppen az elemeket FIFO (first-in-first-out) elv szerint rendezi. A kivtelek kztt van a prioritsi sor, amelyik rendezi az elemeket valamilyen szempont alapjn. Brmilyen rendezst hasznlunk, a sor elejn van az az elem, amit legelszr el szeretnnk tvoltani a remove vagy a poll metdus meghvsval. A FIFO sor minden j elemet a sor vgre illeszt be. Ms fajta sorok hasznlhatnak ms elhelyezsi szablyokat.
Megjegyzs: A Queue gyjtemnyekkel terjedelmi okokbl a tovbbiakban nem foglalkozunk.
Map
A kulcsokat rtkekk kpezi le. A lekpezsek nem tartalmazhatnak dupliklt kulcsokat. Minden egyes kulcs legfeljebb egy rtket tud lekpezni. Msknt fogalmazva a Map kulcs-rtk prokat trol.
196. oldal
SortedSet
Az elemek nvekv sorrendben trolst teszi lehetv. Szmos kiegszt mvelettel biztostja, hogy kihasznlhassuk a rendezettsget. Ezt az interfszt szoktk hasznlni olyan rendezett halmazknt, mint pldul egy szlista vagy tagsgi lista.
SortedMap
A lekpezsek kulcs szerinti nvekv sorrendbe trolst teszi lehetv. A rendezett lekpezst hasznljuk a rendezett gyjtemnyek kulcs/rtk prjainl. Ilyen pldul a sztr vagy a telefonknyv.
21.2.2
A Collection interfsz
Az interfsznek van metdusa, ami megmondja hny elem van a gyjtemnyben (size, isEmpty), leellenrzi, hogy az adott objektum benne van-e a gyjtemnyben (contains), hogy hozzadjon elemet gyjtemnyhez vagy elvegye belle (add, remove), bejrt (ms nven itertort) szolgltat a bejrshoz (iterator). Az add metdus boolean visszatrsi rtke azt jelzi, hogy trtnt-e a gyjtemnyben vltozs. Ugyanis olyan implementci esetn, ahol az elemek tbbszrs trolsa nem megengedett, nem trtnik vltozs, ha az elemet mr eleve tartalmazta a gyjtemny. Hasonlan, a remove metdus esetn csak akkor vltozik a gyjtemny llapota, ha benne volt az adott elem, s gy sikeres volt a kivtel.
A gyjtemnyek bejrsa
Kt mdja van hogy bejrjuk a gyjtemnyeket. Az egyik a for-each ciklussal, a msik az itertorok hasznlatval.
197. oldal
A for-each ciklus megengedi, hogy bejrjuk a gyjtemnyt vagy tmbt a for ciklus hasznlatval. A kvetkez kd a for-each ciklust hasznlja, s minden elemet kln sorban jelent meg:
for (Object o : collection) System.out.println(o);
Itertorok Az itertor egy olyan objektum, ami megengedi, hogy bejrjuk a gyjtemnyt s eltvoltsuk az elemeket a gyjtemnybl, ha akarjuk. Az Iterator interfsz:
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); // Optional }
A hasNext metdus visszatrsi rtke true, ha az itercinak van mg be nem jrt eleme. A remove metdus eltvoltja a gyjtemnybl az utols elemet, amit a next hvsra kaptunk. A remove metdus kivtelt dob, ha mg nem volt kiolvasott elem. Az Iterator.remove az egyetlen biztonsgos t, hogy mdostsuk a gyjtemnyt az iterci folyamn. A viselkeds meghatrozatlan, ha a gyjtemny ms egyb ton mdostva lett, amg az iterci folyamatban volt. Itertor hasznlata clszer a for-each ciklus helyett a kvetkez esetekben: Trlni szeretnnk a bejrs kzben. Ki szeretnnk cserlni az elemeket. Egyszerre tbbfle bejrsra is szksg van.
A kvetkez metdus mutatja, hogyan hasznljuk az itertort szrnek egy tetszleges gyjtemnyben (ezzel ttekintjk, hogy a gyjtemny hogyan tvoltja el a specifikus elemeket):
static void filter(Collection c) { for (Iterator i = c.iterator(); i.hasNext(); ) if (!cond(i.next())) i.remove(); }
Ez az egyszer kis kdrszlet sokoldal, ami azt jelenti, hogy mkdik brmely gyjtemnyben, kivtel nlkl minden implementciban. Ez a plda bemutatja, milyen knyny sokoldal algoritmust rni a Gyjtemny keretrendszer segtsgvel.
198. oldal
containsAll true a visszatrsi rtke, ha a cl gyjtemny tartalmaz minden elemet a meghatrozott gyjtemnyben (rszhalmaz) addAll Minden elemet hozzad a meghatrozott gyjtemnyhez (uni) removeAll Eltvoltja a clgyjtemnybl az sszes olyan elemet, amit a meghatrozott gyjtemny tartalmazott (klnbsg) retainAll Eltvoltja a clgyjtemnybl az sszes olyan elemet, amit a meghatrozott gyjtemny nem tartalmazott. Azaz, csak azokat tartja meg a clgyjtemnyben, amiket a meghatrozott gyjtemny is tartalmazott. (metszet) clear Eltvoltja az sszes elemet a gyjtemnybl.
Az addAll, removeAll, s a retainAll metdus mindig true-val tr vissza, ha a clgyjtemny mdostva volt a mvelet vgrehajtsa alatt. Egy egyszer plda tmeges metdusok erejrl: a kvetkez kifejezs eltvoltja az e elem minden pldnyt a c gyjtemnybl:
c.removeAll(Collections.singleton(e));
A kifejezs hasznlja a Collections.singleton metdust, amelyik egy statikus gyrt metdus, ami visszaad egy olyan gyjtemnyt, amely csak egy meghatrozott elemet tartalmaz.
Tegyk fel, hogy c ismert s csak sztringet tartalmaz (c tpusa Collection<String>). Ekkor hasznlhat a kvetkez vltozat is:
String[] a = c.toArray(new String[0]);
21.2.3
A Set interfsz
A Set egy specilis Collection, amely nem tartalmaz dupliklt elemeket. A Set nem tartalmaz j metdust a Collection-tl rkltekhez kpest. A Set a tartalmazott objektumok
21.Gyjtemnyek
199. oldal
equals s a hashcode metdust hasznlja arra, hogy a tbbszrs trolst kiszrje. Kt Set objektum akkor egyenl, ha ugyanazon elemeket tartalmazzk. A Set interfsz:
public interface Set<E> extends Collection<E> { // Basic Operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); // Optional boolean remove(Object element); // Optional Iterator iterator(); // Bulk Operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); // Optional boolean removeAll(Collection<?> c); // Optional boolean retainAll(Collection<?> c); // Optional void clear(); // Optional // Array Operations Object[] toArray(); <T> T[] toArray(T[] a);
A Java platform hrom ltalnos Set implementcit tartalmaz: a HashSet, TreeSet, s LinkedHashSet. HashSet esetn az elemeket egy hash tblban trolja, ez a legjobb vlaszts, ha az elemek bejrsa nem fontos. A TreeSet az elemeket egy piros-fekete fban trolja, ami az elemek bejrst hatkonyan meg tudja valstani, de egy elem elrse, beszrsa lassabb, mint a HashSet esetn. A LinkedHashSet tvzi a lncolt listkat a hash tblval. Nzznk egy egyszer pldt. Felttelezzk, hogy van egy c nev Collection-nk, s szeretnnk mg egy Collection-t ltrehozni, amely ugyanazokat az elemeket tartalmazza, de minden elemet csak egyszeresen.
Collection<Type> noDups = new HashSet<Type>(c);
Ltrejn egy Set, amely nem tartalmaz dupliklt elemeket, de a c sszes eleme benne van. Az alaprtelmezett konverzis konstruktort hasznljuk a tnyleges ltrehozsra.
Megjegyezzk, hogy a referencia tpust szoks interfsz tpussal (Set) lerni, mg az objektum tpusa egy implementcis osztly lesz (HashSet). Ez egy nagyon ajnlott programozsi gyakorlat, amivel knnyebb rugalmas kdot kszteni. Ha ksbb esetleg abc sorrendben akarjuk a szavakat kirni, csupn le kell cserlni HashSet-et TreeSet-re. Ez az egyszer, egysoros vltoztats ilyen eredmnyt produkl:
Duplicate word: i Duplicate word: i 4 distinct words: [came, i, left, saw]
Ha azt szeretnnk, hogy az uni, metszet vagy klnbsg kpzs sorn egyik halmaz se mdosuljon (ahogy az matematikailag is vrhat), akkor a kvetkez mdon kell alkalmazni a metdusokat:
Set<Type> union = new HashSet<Type>(s1); union.addAll(s2); Set<Type> intersection = new HashSet<Type>(s1); intersection.retainAll(s2); Set<Type> difference = new HashSet<Type>(s1); difference.removeAll(s2);
Nzzk meg jra a FindDups programot. Azt akarjuk tudni, hogy melyik szavak fordulnak el egyszer a vitatott listban, s mely szavak fordulnak el tbbszr, de nem akarunk dupln kirt szavakat ltni. Ezt gy tudjuk elrni, hogy kt halmazt hozunk ltre: az egyik minden elemet tartalmaz, a msik csak a duplikltakat. Nzzk a programot:
import java.util.*; public class FindDups2 { public static void main(String args[]) { Set<String> uniques = new HashSet<String>(); Set<String> dups = new HashSet<String>();
21.Gyjtemnyek
for (String a : args) if (!uniques.add(a)) dups.add(a);
201. oldal
// Destructive set-difference uniques.removeAll(dups); System.out.println("Unique words: " + uniques); System.out.println("Duplicate words: " + dups); } }
Ha lefuttatjuk az elz parancssori paramterlistval (i came i saw i left), akkor a kvetkez eredmnyt kapjuk:
Unique words: [left, saw, came] Duplicate words: [i]
A symmetricDiff-ben elszr a kt halmaz unijt lltjuk el az addAll metdussal, majd a temp-ben ellltott metszetet kivonjuk belle a removeAll metdussal.
21.2.4
A List interfsz
A List egy rendezett Collection. A List duplikltan is tartalmazhat elemeket. A Collection-bl rklt metdusokon kvl a List interfsz a kvetkez lehetsgeket tartalmazza: Pozci szerinti elrs: Az elemek a listban betlttt helyk alapjn is elrhetk. Keress: A megadott elemet kikeresi a listbl, s visszaadja a pozcijt. Bejrs: Az Iterator alap szolgltatsok bvltek. Rszlista: Lehetv tesz rszlista mveleteket.
public interface List<E> extends Collection<E> { // Positional Access E get(int index); E set(int index, E element); // Optional boolean add(E element); // Optional void add(int index, E element); // Optional E remove(int index); // Optional abstract boolean addAll(int index, Collection<? extends E> c); //Optional int indexOf(Object o); int lastIndexOf(Object o);
A List interfsz:
202. oldal
Collection metdusok
A metdusok rkldnek a Collection-bl, s mindent az elvrsainknak megfelelen hasznlhatunk. A remove metdus mindig az els elfordul elemet trli a listbl. Az add s addAll metdusnl az elem a lista vgre kerl. Pldul a list1 vgre msolja a list2 elemeit.
list1.addAll(list2);
A kvetkez kd elkszti a list3 nev listt, amelynek eredmnye ugyanaz, mint az elznek, de nem rontja el list1-et:
List<Type> list3 = new ArrayList<Type>(list1); list3.addAll(list2);
Kt List objektum akkor egyenl, ha ugyanazok az elemek ugyanolyan sorrendben fordulnak el benne.
Az algoritmus tallomra felcserli az adott list elemeit Ez egy egyszer mdszer a keversre. Msrszt az sszes kevers valsznsge megegyezik, feltve, hogy a forrs is vletlenszer, valamint gyors (csal list.size()-1 csere trtnt). A kvetkez program bemutat egy plda felhasznlst:
21.Gyjtemnyek
import java.util.*; public class Shuffle { public static void main(String args[]) { List<String> list = new ArrayList<String>(); for (String a : args) list.add(a); Collections.shuffle(list, new Random()); System.out.println(list); } }
203. oldal
A programot mg rvidebb s gyorsabb tudjuk tenni. Az Array osztlynak van egy asList nev statikus metdusa, ami egy tmb elemeit List-knt is elrhetv teszi. Ez a metdus nem msolja t a tmb elemeit, csupn referencikkal dolgozik, s ugyanazok az elemek a listbl s a tmbbl is elrhetk. A visszaadott List objektum nem tartalmazza az opcionlis add s remove metdusokat, hiszen a tmb mrete nem vltozhat. Nzzk meg a kvetkez kdot:
import java.util.*; public class Shuffle { public static void main(String args[]) { List<String> list = Arrays.asList(args); Collections.shuffle(list); System.out.println(list); } }
Itertorok
A List interfsz esetn termszetesen hasznlhat az stl rklt mdszer a bejrsra, de van egy ennl tbb lehetsget nyjt megolds is: a ListIerator. Ez az interfsz megengedi a lista ktirny bejrst s az ehhez kapcsold tovbbi mveleteket. A ListIterator interfsz:
public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); boolean hasPrevious(); E previous (); int nextIndex(); int previousIndex(); void remove(); // Optional void set(E o); // Optional void add(E o); // Optional }
Hrom metdust (hasNext, next s remove) az Iterator-tl rklte, a hasPrevious s previous a visszafel trtn bejrst tmogatja. A kvetkez plda visszafel jrja be a listt:
for (ListIterator<Type> i = list.listIterator(list.size()); i.hasPrevious(); ) { Type t = i.previous(); ... }
204. oldal
A List interfsz ktfle paramterezssel tud ListIterator-t gyrtani. Paramter nlkl a lista elejre pozcionl, mg az int paramtert vr verzi esetn a paramter alapjn pozcionl ListIterator tr vissza a listIterator metdus. Az index vagy kurzor pozci a kvetkez alapjn rtend: n hosszsg lista esetn n+1 rvnyes rtke van az indexnek, 0-tl n-ig minden egsz. Az index mindig kt elem kztt van a kvetkez bra szerint:
Ha az indexOf metdus visszatrsi rtke i.previosIndex(), akkor megtallta a keresett objektumot. Az Iterator interfsz szolgltatsa a remove metdus, mely a gyjtemnybl eltvoltja az adott elemet. A ListIterator interfsz tovbbi kt metdust nyjt, amely mdostja a listt: set s add. A set metdus fellrja az aktulis elemet. A kvetkez metdus hasznlja set metdust az adott elem sszes elfordulsnak cserlse sorn:
public static <E> void replace(List<E> s, E val, E newVal) { for (ListIterator<E> i = s.listIterator(); i.hasNext(); ) if (val==null ? i.next()==null : val.equals(i.next())) i.set(newVal); }
Egy kis trkk van ebben a pldban a val s az i.next() egyenlsg vizsglatban. Ha a val rtke null, akkor a NullPointerException kivtel nem vltdik ki, hiszen ha val rtke null lenne, akkor a feltteles opertor msik ga rtkeldik ki. Az add metdussal j elemeket adhatunk a List-hez az aktulis kurzorpozci el. A kvetkez plda bemutatja, hogy hogyan lehet a val minden elfordulst kicserlni a newVals listval:
public static <E> void replace(List<E> s, E val, List<E> newVals) { for (ListIterator<E> i = s.listIterator(); i.hasNext(); ){ if (val==null ? i.next()==null : val.equals(i.next())) { i.remove(); for (E e : newVals) i.add(e); } } }
Rszlista mvelet
A subList(int fromIndex, int toIndex) rszlista metdus visszaadja a lista egy szelett, a paramterknt megadott indexek figyelembevtelvel: fromIndex rsze, de toIndex nem
21.Gyjtemnyek
205. oldal
rsze a visszaadott szeletnek. (Emlkeztetl: a String osztly substring metdusa is gy mkdik.) Ezrt gyakori plda a kvetkez:
for (int i = fromIndex; i < toIndex; i++) { ... }
A visszaadott lista kapcsolatban marad az eredeti listval. gy brmilyen mdosts trtnik a rszlistn, az hatssal lesz az eredetire is, st ez fordtva is igaz. Ezrt nincs szksg tovbbi rszlista metdusokra. Nzznk erre egy olyan pldt, amikor a lista egy rszt akarjuk trlni:
list.subList(fromIndex, toIndex).clear();
Arra rdemes figyelni, hogy itt a visszaadott indexek a tallt elemek rszlistabeli indexeit jelentik, nem az eredeti list-belieket. A kvetkez metdus is a subList-et hasznlja, hogy knnytse a munkt. A feladata az, hogy a lista egy adott mret vgt levgja, s egyben vissza is adja azt. Msknt fogalmazva egy index mentn trtn sztvgsrl van sz:
public static <E> List<E> dealHand(List<E> deck, int n) { int deckSize = deck.size(); List<E> handView = deck.subList(deckSize - n, deckSize); List<E> hand = new ArrayList<E>(handView); handView.clear(); return hand; }
A kvetkez program az elz dealHand metdust hasznlja a Collection.suhffle-val egytt, hogy 52 lapbl osszon le. A program 2 parancssori paramtert hasznl: a kezek szmt s az egy kzbe osztand lapok szmt:
import java.util.*; class Deal { public static void main(String[] args) { int numHands = Integer.parseInt(args[0]); int cardsPerHand = Integer.parseInt(args[1]); // Make a normal 52-card deck String[] suit = new String[] {"spades", "hearts", "diamonds", "clubs"}; String[] rank = new String[] {"ace","2","3","4","5","6","7","8", "9","10","jack","queen","king"}; List<String> deck = new ArrayList<String>(); for (int i = 0; i <suit.length; i++) for (int j = 0; j <rank.length; j++) deck.add(rank[j] + " of " + suit[i]); Collections.shuffle(deck); for (int i=0; i<numHands; i++) System.out.println(dealHand(deck, cardsPerHand)); } }
[8 of hearts, jack of spades, 3 of spades, 4 of spades, king of diamonds] [4 of diamonds, ace of clubs, 6 of clubs, jack of hearts, queen of hearts] [7 of spades, 5 of spades, 2 of diamonds, queen of diamonds, 9 of clubs] [8 of spades, 6 of diamonds, ace of spades, 3 of hearts, ace of hearts]
List algoritmusok
A Collections osztly nagyon hatkonyan hasznlhat algoritmusokat nyjt listk kezelsre. A kvetkez lista csak felsorolja a fontosabbakat: sort: Rendezi a listt. shuffle: Vletlenszeren felcserl elemeket a listban. (Permutl.) reverse: Megfordtja az elemek sorrendjt a listban. rotate: Megforgatja az elemeket. swap: Felcserl kt meghatrozott pozciban lev elemet. replaceAll: Az sszes elfordul elemet kicserli egy msikra. fill: Fellrja az sszes elemet egy meghatrozott elemre. copy: tmsolja a forrslistt egy cllistba. binarySearch: Egy elemeket keres a binris keressi algoritmust hasznlva. indexOfSubList: Visszatr az els olyan indexszel, amelynl kezdd rszlista egyenl a msik listval. lastIndexOfSubList: Visszatr az utols olyan indexszel, amelynl kezdd rszlista egyenl a msik listval.
21.2.5
Map interfsz
A Map olyan trol, ami kulcs-rtk prokat tartalmaz. A Map nem tud trolni dupliklt kulcsokat, egy kulcshoz csak egy rtk rendelhet. A Map interfsz:
public interface Map { V put(K key, V value); V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); void putAll(Map<? extends K,? extends V> t); void clear();
21.Gyjtemnyek
public Set<K> keySet(); public Collection<V> values(); public Set<Map.Entry<K,V>> entrySet(); public interface Entry { K getKey(); V getValue(); V setValue(V value); }
207. oldal
A Java platform hrom klnbz Map implementcit tartalmaz: HashMap, TreeMap, LinkedHashMap.
} }
A program kimenete:
8 distinct words: {to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}
Ha betrendi sorrendbe akarjuk rendezni, akkor a HashMap-et TreeMap-re kell cserlni, s a kvetkezket rja ki a kpernyre:
8 distinct words: {be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1}
Ha a felbukkans sorrendjre vagyunk kvncsiak, akkor ez a LinkedHashMap-el tegyk, s a kimenet a kvetkez lesz:
8 distinct words: {if=1, it=2, is=2, to=3, be=1, up=1, me=1, delegate=1}
Kt Map objektum knnyedn sszehasonlthat. Akkor egyenlek, ha a kulcs-rtk prjaik megegyeznek. (A sorrend nem szmt.)) A Map konstruktora egy j Map objektumot hoz ltre egy mr meglv Map objektum tartalmval.
208. oldal
Map<K, V> copy = new HashMap<K, V>(m);
Collection nzetek
A Map tartalmt hromfle szempont alapjn nzhetjk vissza: keySet: kulcsok halmaza (Set) values: rtkek gyjtemnye (Collection) entrySet: kulcs-rtk prok halmaza (Set)
for (KeyType key : m.keySet()) System.out.println(key);
Ugyanez itertorral:
for (Iterator<Type> i=m.keySet().iterator(); i.hasNext(); ) if (i.next().isBogus()) i.remove();
21.2.6
Objektumok rendezse
Ha a lista String-eket tartalmaz, akkor azt (Unicode-beli) abc sorrendbe rendezhetjk. Ha pedig Dtum (Date) tagokat tartalmaz, akkor idrendi sorrendbe. Hogyan trtnik ez? A String s a Date is megvalstjk a Comparable interfszt. Ez az interfsz tartalmazza a legltalnosabb rendezsi eljrsokat, amely megengedi az osztlynak, hogy automatikusan rendezve legyen valamely szempont szerint. A kvetkez tblzat sszefoglalja a legfontosabb osztlyokat, amelyek az interfszt megvalstjk.
21.Gyjtemnyek Osztly Byte Character Long Integer Short Double Float BigInteger BigDecimal Boolean File String Date CollationKey Alaprtelmezett sorrend eljeles szm eljelnlkli szm eljeles szm eljeles szm eljeles szm eljeles szm eljeles szm eljeles szm eljeles szm false < true rendszerfgg abc szerinti a teljes nv alapjn abc szerinti idrendi abc szerinti a helyi jellemzk alapjn
209. oldal
Ha a listnk olyan objektumokat tartalmaz, amelyek nem valstjk meg a Comparable interfszt, akkor a Collections.sort(list) hvs ClassCastException kivtelt fog dobni.
A comprateTo metdus sszehasonltja az objektumot az tvett objektummal, s visszatrsi rtke negatv egsz, nulla, vagy pozitv egsz, ha az tvev objektum kisebb, egyenl vagy nagyobb, mint az tvett objektum. Ha a metdus nem tudja sszehasonltani a kt objektumot, akkor ClassCastException-t dob. A kvetkez osztly emberek nevt tartalmazza sszehasonlt eszkzkkel kiegsztve:
import java.util.*; public final class Name implements Comparable<Name> { private final String firstName, lastName;
210. oldal
public int hashCode() { return 31*firstName.hashCode() + lastName.hashCode(); } public String toString() { return firstName + " " + lastName; } public int compareTo(Name n) { int lastCmp = lastName.compareTo(n.lastName); return (lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName)); } }
Ebben a rvid pldban az osztly nmileg korltozott: nem tmogatja a kzps nevet, ktelez megadni a vezetk- s keresztnevet, s nem veszi figyelembe a nyelvi sajtossgokat. Azonban gy is illusztrl nhny fontos pontot: A konstruktor ellenrzi, hogy az paramterei null rtkek-e. Ez minden ltrejv Name objektum szmra biztostja, hogy jl formzott legyen, gy semelyik ms metdus nem dob NullPointerException-t. A hashCode metdus jradefinilt. (Azonos objektumoknak azonos hash kdjuknak kell lennie) Az equals metdus false rtkkel tr vissza, ha a paramterknt kapott msik objektum null, vagy helytelen tpus. Ilyen esetben a compareTo metdus futsidej kivtelt dob. A toString metdus jradefinilsval a Name olvashat formban jelenthet meg. Ez mindig j tlet, klnsen olyan objektumok esetn, amiket gyjtemnybe helyeznk. A klnbz tpus gyjtemnyek toString metdusai jl olvashat formban jelentik meg a gyjtemnyek tartalmt. A comparateTo metdus sszehasonltja az objektumok legfontosabb rszt (lastName). (Mint ahogy itt is, mskor is gyakran tudjuk hasznlni a rszek tpusa szerinti alaprtelmezett rendezst.) A lastName adattag String tpus, gy az alaprtelmezett rendezs pontosan megfelel lesz. Ha az sszehasonltsi eredmnyek nulltl klnbzek, amely egyenlsget jelent, ksz vagyunk: csak vissza kell adni az eredmnyt. Ha a legfontosabb rszek egyenlk, sszehasonltjuk a kvetkezket (itt firstName). Ha ez alapjn sem dnthet el a sorrend, tovbblpnk.
211. oldal
} }
A Comparator-ok
Hogyan tudjuk az objektumokat az alaprtelmezett rendezstl eltr ms sorrendbe rendezni? Ilyen esetben jn jl a Comparator interfsz, amely egyetlen egyszer metdust tartalmaz:
public interface Comparator<T> { int compare(T o1, T o2); }
A compare metdus sszehasonltja a kt paramtert, visszatrsi rtke negatv egsz, nulla, vagy pozitv egsz, ha az els paramter kisebb, egyel vagy nagyobb, mint a msodik. Ha valamelyik paramter helytelen tpus a Comparator szmra, a compare metdus ClassCastException-t dob. Tegyk fel, hogy van egy Employee nev osztlyunk:
public class Employee implements public Name name() { ... public int number() { ... public Date hireDate() { ... ... } Comparable<Employee> { } } }
Ha az Employee objektumok alaprtelmezett rendezse a Name tag szerinti, akkor nem egyszer a legmagasabb rang dolgozkat kikeresni a listbl. A kvetkez program elkszti a listt:
import java.util.*; class EmpSort { static final Comparator<Employee> SENIORITY_ORDER = new Comparator<Employee>() { public int compare(Employee e1, Employee e2) { return e2.hireDate().compareTo(e1.hireDate()); } }; // Employee Database static final Collection<Employee> employees = ... ;
212. oldal
21.3. Implementcik
Az implementcik az elz fejezetben lert interfszeket valstjk meg (implementljk). Az albbiakban az implementcik fajtit lthatjuk. ltalnos cl implementcik: a leggyakrabban hasznlt implementcik, mindennapos hasznlatra terveztk Specilis cl implementcik: arra terveztk, hogy specilis helyzetekben esetben hasznljuk. Nem szabvnyos teljestmny karakterisztikk megjelentsre, hasznlati s viselkedsi korltozsokra. Konkurens implementcik: ers konkurencia tmogatsra terveztk, tbbnyire az egyszl teljestmny rovsra. Ezek az implementcik a java.util.concurrent csomag rszt kpzik. Csomagol implementcik: a tbbi implementcival sszekombinlva hasznlhatk (gyakran az ltalnos clval), hogy extra funkcionalitst biztostsanak, vagy bizonyos funkcikat korltozzanak Knyelmi implementcik: mini implementcik, tipikusan a gyrt metdusokon keresztl rhetk el. Knyelmes s hatkony alternatvt biztostanak az ltalnos cl implementcik szmra specilis esetekben. Absztrakt implementcik: vzlatos implementcik, amik megknnytik az egyni implementcik ltrehozst.
A tblzatban lthat hogy a Set, a List s a Map interfszek tbbfajta ltalnos cl implementcija hasznlhat. A SortedSet s a SortedMad interfszeknek nincs sajt sora a tblzatban, ezeknek az interfszeknek egy implementcija van (TreeSet s TreeMap). Az ltalnos cl implementcik mind biztostjk az sszes opcionlis mveletet, amit az interfszek tartalmaznak. Mindegyik megengedi a null elemet mind a kulcsok, mind az rtkek esetn. Egyik sem szinkronizlt. Mindegyik szerializlhat (Serializable), s biztost egy publikus clone metdust. A korbbival ellenttes elkpzelst jelent az a tny, hogy ezek az implementcik nem szinkronizltak. A rgebbi Vector s Hashtable gyjtemnyek szinkronizltak. A jelenle-
21.Gyjtemnyek
213. oldal
gi megkzelts azrt alakult ki, mert a gyjtemnyeket srn hasznljk olyan helyeken, ahol a szinkronizlhatsg nem jelent elnyt. Ilyenek pldul az egyszl hasznlat, csak olvassi hasznlat, s ha egy olyan nagyobb adat objektum rszt kpzik, amely megcsinlja a sajt szinkronizcijt. ltalnos API tervezsi tapasztalat az, hogy ne ktelezzk a felhasznlt olyan szolgltats hasznlatra, amit nem sokszor hasznl. Radsul a szksgtelen szinkronizci adott krlmnyek kztt akr holtpontot is eredmnyezhet. ltalnos szably, hogy programrskor az interfszeken, s nem az implementcikon kell gondolkodni. Ez az oka annak, hogy ebben a fejezetben nincsenek plda programok. Legtbb esetben az implementci megvlasztsa csak a teljestmnyt befolysolja. Ahogy azt a korbbiakban emltettk, egy elnyben rszestett programozi stlus az, ha vlasszunk egy implementcit a Collection ltrehozsakor, s rgtn hozz rendeljk az j Collection-t egy olyan vltozhoz, ami adott interfsz tpus (vagy egy olyan eljrsnak adjuk t a Collection-t, ami egy adott interfsz tpus paramtert vr). gy a program nem fgg majd egy adott implementci esetn az ahhoz hozzadott j metdusoktl, ezltal a programoz brmikor szabadon vltoztathatja az implementcit, mikor jobb teljestmnyt szeretne elrni, vagy a mkdsi rszleteket mdostani.
21.3.1
Hrom ltalnos cl Set implementci ltezik: HashSet, TreeSet, s LinkedHashSet. ltalban egyszer eldnteni azt, hogy melyiket kell hasznlni. A HashSet sokkal gyorsabb, mint a TreeSet (konstans vgrehajtsi id szemben a logaritmikus idvel a legtbb mvelet esetn), de nem biztost rendezhetsget. Ha a SortedSet interfsz mveleteire, vagy egy rtk szerint rendezett itercira van szksg, akkor a TreeSet hasznlata javasolt, egyb esetben a HashSet. A LinkedHashSet bizonyos rtelemben egy tmenetet kpez a HashSet s a TreeSet kztt. Megvalstst tekintve ez egy olyan hash-tbla, aminek elemei egy lncolt lista segtsgvel vannak sszektve, gy rendezett-beszrsos itercit biztost (a legritkbban hasznlt elemet szrja be a legsrbben hasznltba), s majdnem olyan gyorsan fut, mint a HashSet. A LinkedHashSet implementcija megkmli a hasznljt az olyan nem specifiklt, ltalban kaotikus rendezstl, mint a HashSet esetben, valamint a TreeSet esetben felmerl tbblet kltsgektl is. Figyelemre mlt, hogy HashSet hasznlata esetn az itercik szma linerisan arnyos a benne trolt bejegyzsek szmval, valamint a beszrsok szmval (a kapacitssal). Emiatt egy tl magas kezdeti kapacits vlasztsa esetn feleslegesen pazaroljuk az idt s a memrit. Msrszt a tl alacsony kezdeti kapacits vlaszts esetn szintn idt vesztnk azzal, hogy az adatstruktrt mindig t kell msolnunk, mikor a kapacitst nveljk. Ha nem specifiklunk kezdeti kapacitst, akkor az alapbellts lp rvnybe, ami 16. A kapacitst mindig felfele kerektik a legkzelebbi kett hatvnyra. A kezdeti kapacitst a konstruktor int paramtereknt adhatjuk meg. A kvetkez kdsor egy olyan HashSet pldny ltrehozst mutatja be, ahol a kezdeti kapacits 64.
Set<String> s= new HashSet<String>(64);
A LinkedHashSet-nek hasonl belltsi paramterei vannak, mint a HashSet-nek, de az iterci idejt nem befolysolja a kapacits. A TreeSet nem rendelkezik belltsi paramterekkel.
214. oldal
21.3.2
Kt ltalnos cl List implementci ltezik: ArrayList s LinkedList. Leggyakrabban valsznleg az ArrayListet fogjuk hasznlni. Konstans elrsi idt biztost a lista elemeinek pozcionlt elrsekor, egyszer s gyors. Nem szksges csompont objektumot foglalni minden lista elemhez, s kpes kihasznlni a System.arraycopy nyjtotta elnyket, amikor egyszerre tbb listaelemet kell mozgatunk. Abban az esetben, ha gyakran kell elemeket hozzadni egy lista elejhez, vagy iterlni a listn, hogy valamelyik bels elemt kitrljk, akkor rdemes LinkedList-t hasznlni. Ezek a mveletek konstans id alatt vgrehajtdnak egy LinkedList-ben, mg egy ArrayList-ben lineris idejek, de ezrt cserbe nagy rat kell fizetni a teljestmny tern. A pozcionlt elrs lineris idej LinkedList esetn, mg ugyanez konstans ArryList-nl, tovbb ez a konstans-faktor a LinkedList esetben sokkal rosszabb. Az ArrayList-nek egy llthat paramtere a kezdeti kapacitsa. Ez azt hatrozza meg, hogy hny eleme legyen az ArryaList-nek, mieltt nvelni kne az elemek szmt. A LinkedList-nek nincs llthat paramtere.
21.3.3
A hrom ltalnos cl Map Implementci a HashMap, a TreeMap s a LinkedHashMap. Ha szksg van sszegyjttt informcira, a TreeMap-et hasznljuk, ha a legjobb sebessg kell, s nem szksgesek az itercik, hasznlhatjuk a HashMap-et, ha az utbbihoz hasonl sebessg kell s iterci is, akkor hasznljunk LinkedHashMap-et. Hasonlkpp, a Set implementci blokkban minden ugyangy mkdik, mint a Map implementciban.
21.4. Algoritmusok
Ebben a fejezetben a Java platform ltal knlt jra felhasznlhat, sokalak algoritmusok egy rszvel foglalkozunk. Mindegyikk a Collections osztly statikus metdusa. Az algoritmusok szles sklja a List-eknl mkdik. De egy pr tetszleges kollekcik esetben is mkdik.
21.4.1
Rendezs
A sort algoritmus jrarendezi a listt. A mvelet kt formja adott. Az egyszerbb forma veszi a listt, s rendezi azt az elemek termszetes (alaprtelmezett) sorrendjben. Itt egy egyszer program, ami kirja betrendben a parancssori paramtereket:
import java.util.*; public class Sort { public static void main(String args[]) { List<String> l = Arrays.asList(args); Collections.sort(l); System.out.println(l); } }
Futtassuk a programot:
java Sort i walk the line
215. oldal
A program megmutatta, hogy ezt az algoritmust nagyon knny hasznlni. Tegyk fel, hogy vannak anagrammkat tartalmaz szlistink. Szeretnnk kiratni azokat a listk hossza szerinti cskken sorrendben, de csak az adott mretnl (pl. 8) nem kevesebb elem listkat. A kvetkez plda megmutatja, hogy hogyan rhetjk el ezt a sort metdus msodik formjnak segtsgvel. Maguk a szlistk egy m objektumban vannak trolva. Errl levlogatjuk a megfelel hosszsgakat. Ezutn a kd rendezi a listt, sszehasonltst vgez, s vgrehajtja a fordtott mret szerinti rendezst. Vgl a kd ismt vgigfut a listn s kirja az elemeket (a szavak csoportjt):
List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> l : m.values()) if (l.size() >= minGroupSize) winners.add(l); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size() - o1.size(); } }); // Szcsoportok kirsa for (List<String> l : winners) System.out.println(l.size() + ": " + l);
Futtassuk a programot, a minimum anagramma csoport mretvel (8) egytt a kvetkez kimenetet kapjuk:
12: [apers, apres, asper, pares, parse, pears, prase, presa, rapes, reaps, spare, spear] 11: [alerts, alters, artels, estral, laster, ratels, salter, slater, staler, stelar, talers] 10: [least, setal, slate, stale, steal, stela, taels, tales, teals, tesla] 9: [estrin, inerts, insert, inters, niters, nitres, sinter, triens, trines] 9: [capers, crapes, escarp, pacers, parsec, recaps, scrape, secpar, spacer] 9: [palest, palets, pastel, petals, plates, pleats, septal, staple, tepals] 9: [anestri, antsier, nastier, ratines, retains, retinas, retsina, stainer, stearin] 8: [lapse, leaps, pales, peals, pleas, salep, sepal, spale] 8: [aspers, parses, passer, prases, repass, spares, sparse, spears] 8: [enters, nester, renest, rentes, resent, tenser, ternes, treens] 8: [arles, earls, lares, laser, lears, rales, reals, seral] 8: [earings, erasing, gainers, reagins, regains, reginas, searing, seringa] 8: [peris, piers, pries, prise, ripes, speir, spier, spire] 8: [ates, east, eats, etas, sate, seat, seta, teas] 8: [carets, cartes, caster, caters, crates, reacts, recast, traces]
216. oldal
21.4.2
Kevers
A kevers algoritmusa bizonyos rtelemben az ellenkezjt teszi, mint amit a rendezs tesz. Lerombol brmilyen rendezst, ami esetleg tallhat a listban. Ez az jelenti, hogy ez az algoritmus jrarendezi a listt gy, hogy a vletlenszersget hasznlja az sszes azonos valsznsggel bekvetkez permutcihoz, felttelezve a tnylegesesen rendszertelen forrst. Pldul tudjuk hasznlni a keverst egy pakli krtya megkevershez a krtya objektumainak listjban. Ezenkvl hasznos tesztesetek, helyzetek generlshoz is.
21.4.3
Keress
A binris keress algoritmus (binarySearch metdus) elemeket keres a rendezett listban. Ennek az algoritmusnak kt formja van. Az els vesz egy listt s egy elemet, amit keres (egy keres kulcsot). Ez a forma felttelezi, hogy a lista elemei rendezve vannak a termszetes rendezs szerint a trolban. A msodik forma nem az alaprtelmezett rendezst alkalmazza, hanem mg egy Comparator paramtert is vr. A visszatrsi rtk azonos mindkt formban. Ha a lista tartalmazza keresett elemet, visszatr az indexvel. Ha nem, a visszatrsi rtk negatv, s egyben utal arra is, hogy hol kellene lennie az elemnek, ha szerepelne a listban. A kvetkez plda keresi egy adott elem megltt, s beilleszti a helyre, ha mg nem szerepel:
int pos = Collections.binarySearch(list, key); if (pos < 0) l.add(-pos-1);
21.Gyjtemnyek A TreeSet osztly implementlja a Set interfszt. Minden kollekci implementlja az Iterator interfszt. A kollekciban lehet primitv adatokat is trolni.
217. oldal
Melyik interfszt rdemes alkalmazni? Olyan trol objektumra van szksgnk, amelyikbe egyedi elemeket akarunk trolni. A sorrend nem lnyeges, de a tbbszrs trols semmikppen sem megengedett. Set List Map
Mit tesz egy Set objektum annak rdekben, hogy ne legyenek dupliklt elemei? Az add metdus kivtelt dob, ha dupliklt elemet akarunk beszrni. Az add metdus false rtket ad vissza, ha dupliklt elemet akarunk beszrni. A dupliklt rtkeket a fordt kiszri.
218. oldal
22.Hlzatkezels
22.1. Hlzati alapok
Az Internetre kttt szmtgpek vagy a TCP (Transmission Controll Protocol) vagy az UDP (User Datagram Protocol) protokollt hasznljk, amint azt az albbi brn is ltni lehet:
Ha egy Java programot runk, ami hasznlja a hlzatot, a felhasznli rteget programozzuk. ltalban nincs szksg a TCP vagy az UDP protokollok kzvetlen hasznlatra, ehelyett hasznlhatjuk az osztlyokat a java.net csomagbl. Ezek az osztlyok rendszerfggetlen hlzati kommunikcit biztostanak. Ha szeretnnk tudni, hogy a programunk pontosan melyik osztlyokat kell, hogy hasznlja, meg kell rteni az alapvet klnbsgeket a TCP s az UDP protokollok kztt.
22.1.1
TCP
Ha kt program megbzhatan akar egymssal kommuniklni, ltrehoznak egy kapcsolatot, s ezen keresztl kldik az adatokat, hasonlan a telefon mkdshez. A TCP akr egy telefontrsasg garantlja, hogy az adat, amit kldnk, helyes sorrendben (!) megrkezik a vevhz. Ha ez nem sikerl, hibajelzst kld vissza. A TCP egy megbzhat pont-pont csatornt ad azoknak az alkalmazsoknak, amelyek megbzhat kapcsolatot kvnnak meg. Ilyen alkalmazsok pldul: Hyper Text Transfer Protokoll (HTTP), File Transfer Protokoll (FTP) s a Telnet. A hlzaton tkldtt s fogadott adatok sorrendje elengedhetetlen az alkalmazsok helyes mkdshez. Mikor a HTTP-t egy URL-bl val olvasshoz hasznljuk, az adatokat olyan sorrendben kell kiolvasnunk, ahogy azt kldtk, klnben knnyen lehetne az eredmny egy sszekuszlt HTML fjl, hibs ZIP fjl, vagy valami ms rvnytelen informci. Definci: a TCP (Transmission Controll Protocol) egy kapcsolat alap protokoll, ami az adatok megbzhat folyamt adja kt szmtgp kztt.
22.1.2
UDP
Az UDP nem ad megbzhat kapcsolatot egy hlzaton lev kt szmtgp kztt, mivel ez nem kapcsolat alap, mint a TCP, inkbb az adatok fggetlen csomagjait kldi az alkalmazsok kztt. Ezeket a csomagokat adatcsomagoknak is hvjuk. A adatcsomagok kldse leginkbb a levelek postn t val kldshez hasonlt: a szllts nem garantlt, a sorrend nem fontos, s mindegyik zenet klnbzik a msiktl.
22.Hlzatkezels
219. oldal
Definci: az UDP (User Datagram Protocol) egy olyan protokoll, ami az adatok olyan fggetlen csomagjait tovbbtja egyik szmtgprl a msikra, amiket adatcsomagoknak hvunk, s nincs garancia a megrkezskre. Az UDP nem kapcsolat alap, mit a TCP. Szmos alkalmazsnl a megbzhatsg garantlsa kritikus, hogy az informci eljusson a hlzat egyik vgrl a msikra. Mindemellett a kommunikci egyb formi nem kvnnak meg olyan szigor normkat. Nzznk pldul egy raszervert, ami a pontos idt kldi el a klienseknek, ha azok ignylik. Ha a kliens hinyol egy csomagot, nem szksges jrakldeni azt, mert az id pontatlan lesz, ha msodik prblkozsra kapja meg. Mikor a kliens kt krst irnyt a szerver fel, s a csomagokat rossz sorrendben kapja, a kliens szreveszi ezt, s jabb krst kld. A megbzhat TCP protokoll ebben az esetben nem szksges, mivel az a teljestmny rovsra mehet, s esetleg csak akadlyozza a szolgltatst. A ping parancs egy msik kitn plda olyan szolgltatsra, ami nem ignyel megbzhat csatornt. A parancs teszteli egy hlzaton lev kt szmtgp kztti kapcsolatot. A parancsnak tudnia kell, hogy a csomag megrkezett-e, hogy megllaptsa, mkdik-e a kapcsolat. Egy megbzhat csatornn ez a szolgltats se mkdik megfelelen. Megjegyzs: Sok tzfal s router gy van konfigurlva, hogy ne engedje t az UDP csomagokat. Ha problmnk van egy, a tzfalon kvl lev szolgltatshoz val kapcsoldssal, vagy a kliens nem tud hozzd csatlakozni, engedlyezzk az UDP kapcsolatokat.
22.1.3
A portokrl ltalnossgban
Ha nagyvonalakban akarunk beszlni, azt mondjuk, a szmtgp egy egyszer fizikai kapcsolaton keresztl kapcsoldik a hlzatra. Minden adat ezen a kapcsolaton keresztl rkezik, br az adatok a szmtgp klnbz programjait hasznljk. Honnan tudja a szmtgp, hogy melyik alkalmazsnak melyik adatot kell tovbbtani? A portok hasznlata ltal. Az adat, amit az interneten keresztl kldenek, el van ltva cmzsi informcival, ami azonostja a clszmtgpet s a portjt. A szmtgp a 32 bites IP cmmel van azonostva, melyet arra hasznlunk, hogy az adat a megfelel szmtgpre rkezzen meg. A portot egy 16 bites szmmal azonostjuk, amit a TCP vagy UDP arra hasznl, hogy az adat a megfelel programhoz jusson. A kapcsolat alap kommunikcinl, mint amilyen a TCP, a szerver program lekt egy foglalatot egy jellemz portnak. Ennek eredmnyekppen a szerver megkap minden adatot, ami ezen a porton keresztl rkezik. A kliens ezutn kommuniklhat a szerverrel a megadott porton keresztl, amit az albbi bra illusztrl:
Definci: a TCP s az UDP protokollok portokat hasznlnak, hogy a bejv adatokat a szmtgp megfelel programjai fel irnytsk. Az adatcsomag alap kommunikcinl, mit amilyen az UDP, az adatcsomag csomagok tartalmazzk a cllloms portszmt, s az UDP irnytja a megfelel helyre a csomagot.
220. oldal
A portok a 0 - 65535 intervallumba kell, hogy essenek, mivel 16 bites szmknt vannak brzolva. A 0 s 1023 kztti portok fent vannak tartva olyan ismert szolgltatsoknak, mit pldul a HTTP vagy az FTP vagy ms rendszerszolgltats. Ezeket a portokat jl ismert portoknak hvjuk. A sajt programjainknak nem szabad lektni ket.
22.1.4
A java programok hasznlhatjk a java.net osztlyain keresztl a TCP vagy UDP protokollokat, hogy kommunikljanak az Interneten. Az URL, URLConnection, Socket s ServerSocket osztlyok mindegyike a TCP-n keresztl kommunikl, mg a DatagramPacket, DatagramSocket s MulticastSocket osztlyok az UDP protokollt hasznljk.
Ahogy ltszik is, az URL kt f komponensbl tevdik ssze: Protokollazonost (Protocol identifier) Erforrs neve (Resource name)
Jegyezzk meg, hogy a protokoll azonost s az erforrs neve kettsponttal s kt perjellel van elvlasztva. A protokoll azonost azt a protokollt jelzi, ami elri a kvnt erforrst. A fenti plda a Hypertext Transfer Protocol-t (HTTP) hasznlja, amit weboldalak elrshez hasznlunk. A HTTP csak egy a sok klnbz protokoll kzl. Hasznljuk mg a File Transfer Protocol-t (FTP), a Gopher, File, News protokollokat. Az erforrs neve tartalmazza az erforrs pontos cmt. A formja fgg a hasznlt protokolltl, de a legtbb protokoll esetben az erforrs nevben benne van az albbi komponensek kzl legalbb egy.
22.Hlzatkezels Hosztnv Fjlnv Portszm Hivatkozs (horgony) A gp neve, amelyen az erforrs van Az elrsi t neve a hoszton
221. oldal
A legtbb protokollnl a hosztnv s a fjlnv ktelez, mg a portszm s a hivatkozs csak opcionlis. Pldul az erforrs nv egy HTTP tpus URL-ben megad egy szervert a hlzaton (hosztnv) s a dokumentum elrsi tjt a gpen (fjlnv), esetleg megad egy portszmot s egy hivatkozst (horgonyt). A Java weboldal URL-ben a java.sun.com a hosztnv.
22.2.1
URL objektumot legegyszerbben egy olyan sztringbl tudunk ellltani, ami ember szmra olvashat formban tartalmazza az URL cmet. Ez ltalban olyan alak, hogy ms is felhasznlhatja az URL-t. Pldul a Gamelan oldal URL-e, ami Java forrsokat hasznl, a kvetkezkppen nz ki:
http://www.gamelan.com/
A Java programban a kvetkezt kell hasznlni, hogy URL objektumot hozzunk ltre:
URL gamelan = new URL("http://www.gamelan.com/");
A fenti URL objektum egy abszolt URL. Az abszolt URL minden informcit tartalmaz, ami szksges lehet, hogy elrjk a forrst. Ezen kvl ltre lehet hozni objektumokat relatv URL cmmel is.
Ezek relatv URL cmek, ahol az URL arra a szerverre hivatkozik, ahol a JoesHomePage oldal is tallhat. A Java programokban ltrehozhatunk URL objektumokat relatv URL-bl is. Pldul tegyk fel, hogy ismernk kt URL-t a Gamelan oldalrl.
http://www.gamelan.com/pages/Gamelan.game.html http://www.gamelan.com/pages/Gamelan.net.html
Hozzunk ltre URL objektumot ezekbl az oldalakbl, hivatkozva a kzs knyvtrukra (http://www.gamelan.com/pages/), mit itt:
URL gamelan = new URL("http://www.gamelan.com/pages/"); URL gamelanGames = new URL(gamelan, "Gamelan.game.html"); URL gamelanNetwork = new URL(gamelan, "Gamelan.net.html");
222. oldal
Ez a kdrszlet az URL azon konstruktort hasznlja, amivel ltrehozhatunk egy URL objektumot egy msik alapjn. A konstruktor ltalnos alakja a kvetkez:
URL(URL baseURL, String relativeURL)
Az els paramter egy URL objektum, ami az j URL bzist jelzi. A msodik paramter egy sztring, ami specifiklja a bzisra hivatkoz forrs nevt. Ha a baseURL nincs megadva, a konstruktor abszolt URL-knt kezeli a relativeURL sztringet. Viszont, ha a relativeURL sztring egy abszolt URL, a konstruktor figyelmen kvl hagyja a baseURL-t. Ez a konstruktor akkor is hasznos lehet, ha olyan URL objektumot akarunk ltrehozni, amiben van horgony (anchor). Tegyk fel, hogy a Gamelan.network.html fjl tartalmaz egy horgonyt, amit BOTTOM-nak hvnak, s a fjl aljra mutat. A kvetkez kd a relatv URL konstruktort hasznlja az objektum ltrehozsra:
URL gamelanNetworkBottom = new URL(gamelanNetwork, "#BOTTOM");
Ms URL konstruktorok
Az URL osztly tartalmaz kt msik konstruktort is az URL objektumok ltrehozshoz. Ezek a konstruktorok akkor hasznosak, ha olyan URL-ekkel dolgozunk, mit pldul a HTTP, ami tartalmaz hosztnevet, fjlnevet, portszmot s hivatkozst (horgonyt) is. Ez a kt konstruktor akkor is hasznos lehet, ha nincs egy olyan sztringnk, ami tartalmazza a komplett URL-t, de ismerjk nhny sszetevjt. Pldul felttelezzk, hogy egy hlzat-tallz panelt fejlesztnk ppen, ami hasonlan mkdik, mint egy fjltallz, vagyis a felhasznl vlaszthat protokollt, hosztnevet, portot s fjlnevet. Ltrehozhatunk URL-t a panel komponenseibl. Az els konstruktor az URL-t a protokollbl, a hosztnvbl, s a fjlnvbl lltja el. Az albbi plda a Gamelan.net.html fjlbl (ami a gamelan oldalon tallhat meg) csinl URL-t.
new URL("http", "www.gamelan.com", "/pages/Gamelan.net.html");
Ez ekvivalens a kvetkezvel:
new URL("http://www.gamelan.com/pages/Gamelan.net.html");
Az els paramter a protokoll, a msodik a hosztnv s az utols a fjl elrsi tja. A fjlnvnek perjellel kell kezddnie. Ez jelzi, hogy a fjl gykere a hosztnvben van megadva. A kvetkez konstruktor egy portszmmal tbb paramtert tartalmaz az elzhz kpest:
URL gamelan = new URL("http", "www.gamelan.com", 80, "pages/Gamelan.network.html");
Ha a fenti konstruktorok egyikvel hozunk ltre URL objektumot, a toString vagy toExternalForm paranccsal ltrehozhatunk egy sztringet, amely tartalmazza a teljes URL cmet.
MalformedURLException
A konstruktorok mindegyike MalformedURLException kivtelt ad vissza, ha valamelyik paramter null, vagy ismeretlen a protokoll. Ezt gy tudjuk lekezelni, ha a konstruktort try/catch blokkba rakjuk, mit a kvetkez kdban:
22.Hlzatkezels
try { URL myURL = new URL(. . .) } catch (MalformedURLException e) { . . . // Kivtelkezel kd . . . }
223. oldal
Megjegyzs: Az URL objektumok egyszer rhatak. Miutn ltrehoztunk egyet, nem lehet megvltoztatni az attribtumait (protokoll, hosztnv, fjlnv vagy portszm). rdemes azt is megemlteni, hogy az URL objektumok hasonlan a korbbi File objektumokhoz a ltrejttkkor nem ellenrzik az URL elrhetsgt, rvnyessgt stb., mivel az URL-nek egyenlre csak egy logikai reprezentcija.
Megjegyzs: Ne felejtse el, hogy egyes URL cmek nem tartalmazzk ezeket a komponenseket. Az URL osztly azrt nyjtja ezeket a metdusokat, mert a HTTP URL-ek s a leggyakrabban hasznlt URL-ek tartalmazni szoktk. Az URL osztly nmikpp HTTP-centrikus.
Ezeket a getXXX metdusokat arra hasznlhatja, hogy informcit kapjon a URL-rl, tekintet nlkl a konstruktorra, amit az URL objektum elksztsre hasznlt. Az URL osztly a metdusokkal egytt megszabadt az URL-ek lland jraelemzstl. Ha adott egy tetszs szerinti URL String, csak ksztennk kell egy URL objektumot, s meghvni valamelyik metdust a szksges informcikrt. Ez a kis pldaprogram kszt egy URL-t egy sztringbl, s ezutn az URL objektum metdusait hasznlva elemzi az URL-t:
import java.net.*; import java.io.*; public class ParseURL { public static void main(String[] args) throws Exception { URL aURL = new URL("http://java.sun.com:80/docs/books/" + "tutorial/index.html#DOWNLOADING"); System.out.println("protocol = " + aURL.getProtocol()); System.out.println("host = " + aURL.getHost()); System.out.println("filename = " + aURL.getFile()); System.out.println("port = " + aURL.getPort()); System.out.println("ref = " + aURL.getRef()); } }
Ez a program kimenete:
224. oldal
Amikor futtatjuk a programot, lthatjuk a parancs ablakban grgetve a HTML elemeket s a szveges tartalmat a http://www.yahoo.com/ cmen tallhat HTML fjlbl. Esetleg a program lellhat kivtellel. Ha a utbbi esemny bekvetkezik, a programunkban be kell lltanunk a proxyt, hogy a program megtallhassa a Yahoo szervert.
Ha lehetsges, az openConnection metdus kszt egy j URLConnection-t, inicializlja, csatlakozik az URL-hez, s visszatr az URLConnection objektummal. Ha valami nem
22.Hlzatkezels
225. oldal
megfelel pldul, a Yahoo szerver nem zemel , akkor az openConnection metdus egy IOException-t dob. Miutn sikeresen csatlakoztunk az URL-hez, rhatunk a csatlakozshoz vagy olvashatunk rla az URLConnection objektum hasznlatval. Ha sikeresen hasznltuk az openConnection-t, hogy kommunikcit kezdemnyezzen egy URL-lel, akkor van egy URLConnection objektumhivatkozsunk. Az URLConnection egy HTTP-centrikus osztly; ennek sok metdusa csak akkor hasznos, ha HTTP URLekkel dolgozik. Azonban a legtbb URL protokoll megengedi, hogy olvasson s rjon a kapcsolatra.
A program kimenete megegyezik az elz kimenettel. Hasznlhatja mind a kt mdszer az URL-bl olvassra. Azonban az URLConnection-bl olvass sokkal hasznlhatbb lehet, mert az URLConnection objektumot hasznlhatja ms feladatokra is (pldul az URL-be rs) egy idben. Mg egyszer, ha a program lell, vagy hibazenetet lt, be kell lltani a proxyt, hogy a program megtallhassa a Yahoo szervert.
URLConnection-ba rs
Sok HTML lap tartalmaz rlapokat szveg mezket s ms GUI objektumokat , hogy bekldje a kitlttt adatokat a szerverre. Miutn begpelte a szksges informcikat s elkldi a krst egy gomb lenyomsval, a bngsznk adatokat r az URL-re a hlzaton keresztl. A szerver fogadja az adatokat, feldolgozza s visszakld egy vlaszt, ltalban egy j HTML oldal formjban. Sok szkript hasznlja a POST metdust a kliens adatainak tovbbtsra. A szerver-oldali szkriptek a POST metdust a bemenetk olvassra hasznljk.
226. oldal
Egy Java program szintn kommuniklhat a szerver oldalon fut szkriptekkel. Egyszeren lehet rni egy URL-be, gy kldve adatokat a szerverre. Ezt a kvetkez lpsekkel tudjuk megtenni: Ksztnk egy URL-t. Nyitunk egy kapcsolatot az URL-hez. Belltjuk a kimen kpessget az URLConnection-on. Kapunk egy kimen folyamot. Ez a kimen folyam sszekapcsolt a szkript bemen folyamval a szerveren. runk a kimen folyamba. Bezrjuk a kimen folyamot.
22.3.1
Mi az a socket?
Normlis esetben a szerver egy specilis szmtgpen fut s van egy socket-je, ami egy specilis port szmra van ktve. A szerver vrakozik, figyeli a socket-et hogy van-e felkrs egy klienstl a kapcsoldsra. A kliens oldalon: A kliens ismeri annak a szmtgpnek a hosztnevt, amelyiken a szerver fut, s annak a portnak a szmt, amelyiken keresztl a szerver kapcsoldva van. A kapcsolatra val felkrshez a kliensnek rintkeznie kell a szerverrel a szerver gpn s port-jn.
Ha minden jl megy, a szerver elfogadja a kapcsolatot. Az elfogads sorn, a szerver egy j socket porthoz kapcsoldik. Kell egy j socket (s termszetesen egy klnbz port szm is), ezrt folytatdik a figyels az eredeti socket-en a kapcsolatkrsre, amg a kliensnek kapcsoldnia kell.
A kliens oldalon, ha a kapcsolat elfogadsra kerlt, a socket sikeresen ltrejtt, s a kliens hasznlni tudja a socket-et a szerverrel val kommuniklsra.
Megjegyzs: a kliens oldali socket nincs sszektve azzal a port szmmal, amit a szerverrel val kapcsolattartsra hasznl. A kliens a helyi kijellt port szmmal azonosthat azon a gpen, amin fut.
A kliens s a szerver kapcsolatot tud ltrehozni a socket-jeik ltal rsra, vagy olvassra.
22.Hlzatkezels
227. oldal
Definci: A socket egy vgpontja egy ktvg kommunikcis hlzatnak, amin kt program fut. A socket egy port szmhoz van ktve, ezrt a TCP rteg azonostani tudja a krst, amit ahhoz krtek, hogy elkldhessk az adatot. A java.net csomag a tartalmaz egy Socket osztlyt, ami alkalmas egy ktirny kapcsolat egyik oldalnak vezrlsre egy, a hlzaton lv msik program fel. Ezen kvl a java.net tartalmazza a ServerSocket osztlyt, amely figyel s elfogadja a kapcsolatot a kliensektl. Ha a webhez akarunk kapcsoldni, az URL osztly s a kapcsold osztlyok (URLConnection, URLEncoder) taln alkalmasabbak, mint a Socket osztly. Valjban az URL viszonylag magas szint kapcsolatot teremt a webbel, s hasznlja a socket-eket.
228. oldal
Az EchoClient olvasni s rni is tud a socket-rl azltal, hogy tkld s tvesz adatot az echo szervertl. Nzzk a program rdekesebb rszeit. A main metdus try blokkjban szerepl sorok kiptik a kapcsolatot a socket-en keresztl a kliens s a szerver kztt, s megnyitjk a PrintWriter-t s a BufferedReader-t a socket-en.
echoSocket = new Socket("taranis", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream()));
Sorrendben az els rsz ltrehozza az j Socket objektumot, s nevet ad neki: echoSocket. A Socket konstruktor hasznlata ignyli annak a gpnek a nevt s a port-jnak a szmt, amelyikkel a kapcsolatot ltre akarjuk hozni. A plda program a taranis host nevet hasznlja. Ez a helyi hlzatunk virtulis gpnek a neve. Mikor futtatjuk a programunkat, akkor sajt szerver gpnk host neve kerljn ide. A 7-es porton figyel az echo szerver. A msodik sor sszekapcsolja a Socket kimenett s a PrintWriter-t. A harmadik sor hasonl ehhez, sszekapcsolja a Socket bemenett s a BufferedReader-t. A plda Unicode karaktereket tud rni a socket-en t. Az EchoClient-nek az adatok socket-en val elkldshez egyszeren a PrintWriter-hez kell rnia. Ahhoz, hogy megkapja a szerver vlaszt, olvasnia kell a BufferedReader-rl. A program htralev rszt ez teszi ki. A while ciklus a program kvetkez rdekes rsze. A ciklus beolvas egy sort egy bizonyos id alatt a szabvnyos bementrl, s azonnal elkldi azt a szervernek a PrintWriter-be val rssal, ami a sockethez kapcsoldik:
String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); }
A while ciklus utols sorban beolvas egy sor szveget a BufferedReader-rl, ami a socket-hez kapcsoldik. A readLine metdus addig vr, amg a szerver vlaszol az informcira az EchoClient-nek. Mikor a readLine vlaszol, az EchoClient kirja a szveget a szabvnyos kimenetre. A while ciklus addig tart, amg a felhasznl be nem gpeli az utols karaktert. Vagyis az EchoClient olvas a felhasznl bemenetrl, majd elkldi ezt az echo szervernek, kap egy vlaszt a szervertl, s utna kirja azt, amg az elr az utols karakterig. A while ciklus ekkor bezrul, s a program folytatdik, futtatja a kd kvetkez ngy sort:
22.Hlzatkezels
out.close(); in.close(); stdIn.close(); echoSocket.close();
229. oldal
A kd e sorai a takartst vgzik. A j program mindig kitakart maga utn, s ez a program is ilyen. Ezek a rszek bezrjk az olvast s az rt, ami a socket-hez kapcsoldik s a szabvnyos kimenetet s bemenetet is, ami a szerverhez kapcsoldik. A sorrend itt nagyon fontos. Be kell zrnunk minden folyamatot, ami a socket-hez kapcsoldik, mieltt kikapcsoljuk magt a socket-et. Socket megnyitsa. Kimeneti s bementi folyam megnyitsa a socket-en. Olvass s rs a szerver protokollja szerint. A folyamatok bezrsa. Socket bezrsa.
230. oldal
23.JDBC adatbzis-kezels
A Java Database Connectivity (JDBC) olyan programozi felletet (API-t) ad a programoz kezbe, amellyel a konkrt adatbzis-kezeltl fggetlenl mkd, adatbzis alap alkalmazsok kszthetk.
Kezd lpsek
Els lpsknt meg kell gyzdni, hogy minden helyes van-e belltva. Ez a kvetkez lpseket tartalmazza: Teleptsk a meghajtt a szmtgpre A meghajt tartalmazza a teleptsre vonatkoz utastsokat. A specilis DBMS-hez (adatbzis-kezelhz) rott JDBC meghajtk teleptse egyszeren annyibl ll, hogy tmsoljuk a meghajtt a szmtgpre; semmilyen klnleges belltsra nincs szksg. A JDBC-ODBC hd (JDBC-ODBC Bridge) teleptse mr nem ennyire egyszer. Akr a Solaris, akr a Windows verzijt hasznljuk, automatikus megkapjuk a JDBCODBC hidat is, amely nmagban nem ignyel semmilyen specilis bellts. Azonban az ODBC igen. Telepts a DBMS-t, amennyiben szksges Amennyiben mg nincs a DBMS felteleptve, kvesse a forgalmaz utastsait a teleptsre vonatkozan. A legtbb esetben a DBMS teleptve van s mkdik az ltalnosan elfogadott adatbzisok brmelyikvel.
Kapcsolat ltestse
Els lpsknt a kapcsolatot kell ltrehozni azzal a DBMS-sel, amit hasznlni akarunk. Ez kt lpst tartalmaz: a meghajt betltst s a kapcsolat megteremtst.
23.JDBC adatbzis-kezels
231. oldal
Meghajt betltse
A hasznland meghajt vagy meghajtk betltse nagyon egyszer, s csak egy kdsort tartalmaz. Pldul a JDBC-ODBC Hd meghajtt a kvetkez kd tlti be:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
A driver dokumentcija megadja, hogy melyik osztlyt kell hasznlni. Amennyiben az osztly neve jdbc.DriverXYZ, a kvetkez kddal tudjuk betlteni:
Class.forName("jdbc.DriverXYZ");
Nem szksges a meghajtt pldnyostani s regisztrlni a DriverManager-rel, mert a Class.forName hvs automatikusan megteszi azt. Amennyiben sajt pldnyt hoznnk ltre, egy szksgtelen duplikci trtnne, igaz, ez nem okozna hibt. Amikor a kd betltdtt, kszen llunk a kapcsolat ltrehozsra a DBMS-sel.
Kapcsolat ltrehozsa
A msodik lps a kapcsolat ltrejtthez, hogy a megfelel meghajt hozz legyen kapcsolva a DBMS-hez. A kvetkez kd bemutatja az ltalnos eljrst:
Connection con = DriverManager.getConnection(url, "myLogin", "myPassword");
Ez a lps is nagyon egyszer, a legnehezebb dolog, hogy mit adjunk meg URL-nek. Amennyiben a JDBC-ODBC hd meghajtt hasznljuk, a JDBC URL gy kezddik: jdbc:odbc:. Az URL tbbi rsze ltalban az adatbzis vagy az adatbzis sma neve. Pldul, ha ODBC-t hasznlunk egy Fred nev ODBC adatforrs elrshez, a JDBC URL a kvetkez lesz: jdbc:odbc:Fred. A mylogin helyre a DBMS-ben hasznlt felhasznli nevet, amg a myPassword helyre a jelszt kell behelyettesteni. Azaz, ha a DBMS-hez a bejelentkezsi nv Fernanda, s a jelsz J8, csak erre a kt sorra van szksg, hogy a kapcsolat ltrejjjn:
String url = "jdbc:odbc:Fred"; Connection con = DriverManager.getConnection(url, "Fernanda", "J8");
Amennyiben egy kls cg ltal fejlesztett JDBC-t hasznlunk, a dokumentci megmondja, milyen protokollt hasznljunk, mit kell a jdbc: utn rnunk a JDBC URL-ben. Pldul, ha a meghajt fejlesztje az acme nevet regisztrlta, az els s a msodik rsze az URL-nek a jdbc:acme:. A dokumentci tmutatt tartalmaz a JDBC URL tovbbi rszhez is. A JDBC URL utols rsze tartalmazza az adatbzis azonostsra szolgl informcikat. Amennyiben valamelyik betlttt meghajt azt rzkeli, hogy a JDBC URL a DriverManager.getConnection metdussal lett betltve, a meghajt fogja ltrehozni a kapcsolatot a DBMS-sel a JDBC URL-ben megadott mdon. A DriverManager osztly (hen a nevhez) a httrben lekezeli a kapcsolds sszes rszlett. Ha nem runk sajt meghajtt, taln soha nem is fogjuk a Driver interfsz ms metdust hasznlni, s az egyetlen DriverManager metdus, amit igazn szksges ismernnk, a DriverManager.getConnection. A DriverManager.getConnection metdus ltal visszaadott kapcsolat egy nyitott kapcsolat, amelynek JDBC mondatokat adhatunk meg, amely eljuttatja az SQL mondatot a DBMS-nek. Az elz pldban con egy nyitott kapcsolat, s a kvetkez pldhoz fogjuk hasznlni.
232. oldal
Elszr ltrehozzuk az egyik tblt a plda adatbzisban. Ez a tbla a Coffees, mely tartalmazza az alapvet informcikat a Coffee Break ltal eladott kvkrl, idertve a kv nevt, annak rt, aktulis hten eladott mennyisget s a napi eladott mennyisget. A Coffee tbla lthat itt, melyet ksbb rszletesebben lerunk: COF_NAME Colombian French_Roast Espresso Colombian_Decaf French_Roast_Decaf SUP_ID 101 49 150 101 49 PRICE 7.99 8.99 9.99 8.99 9.99 SALES 0 0 0 0 0 TOTAL 0 0 0 0 0
A COF_NAME mez, amely a kv nevt trolja, maximum 32 karakter hossz VARCHAR tpus. Miutn minden egyes kvtpust klnbz nvvel ltunk el, a nv egyrtelmen meghatrozza az egyes kvkat, gy ez lehet a tbla elsdleges kulcsa. A SUP_ID a kv-kiegszt egyedi azonostjt tartalmazza, SQL tpusa INTEGER. A harmadik mez neve PRICE, tpusa FLOAT, mert tizedes szm trolsra van szksg.
Megjegyzs: A pnz adat ltalban SQL DECIMAL vagy NUMERIC tpus mezben troldik, de a DBMS-k kztti klnbsg miatt, s hogy elkerljk az inkompatibilitst valamelyik rgebbi JDBC-vel, most az ltalnosabb FLOAT tpust hasznljuk.
A SALES mez INTEGER tpus adatokat trol, s megmutatja, hogy mennyi kv lett eladva az adott hten. Az utols mez a TOTAL, amely INTEGER tpus, s megadja, hogy mennyi kvt adtak el sszesen az adott napig. Az adatbzis SUPPLIERS nev tblja, amely informcit trol az egyes kv-kiegsztkrl: SUP_ID 101 49 150 SUP_NAME Acme, Inc. Superior Coffee The High Ground STREET 99 Market Street 1 Party Place 100 Coffee Lane CITY Groundsvill e Mendocino Meadows STATE CA CA CA ZIP 95199 95460 93966
A COFFEES s a SUPPLIERS tbla is tartalmazza a SUP_ID mezt, ezrt ez a mez hasznlhat a SELECT utastsoknl, hogy a kt tblt ssze tudjuk kapcsolni. A SUP_ID oszlop az egyedi azonostja a SUPPLIERS tblnak. A COFFEES tblban pedig idegen kulcsknt szerepel. (Azrt idegen kulcs, mert ez egy msik tblbl lett importlva.) Minden egyes SUP_ID csak egyszer szerepel a SUPPLIER tblban, hiszen ez az elsdleges kulcsnl kvetelmny. A COFEE tblban, ahol idegen kulcsknt szerepel, teljesen termszetes, hogy tbbszrsen megjelenik, hiszen egy
23.JDBC adatbzis-kezels
233. oldal
kiegszt eladhat tbb tpus kvhoz is. A fejezet ksbbi rszben bemutatunk nhny pldt az elsdleges s az idegen kulcs hasznlatra a SELECT lekrdezsekben. A kvetkez SQL utasts ltrehozza a COFFEES nev tblt. A kt kls zrjel tartalmazza az egyes oszlopok nevt s SQL tpust vesszvel elvlasztva. A VARCHAR tpusnl zrjelek kztt megadhat annak maximlis hossza. A pldakd megadja, hogy a COF_NAME oszlop maximum 32 karakter hossz lehet:
CREATE TABLE COFFEES ( COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, SALES INTEGER, TOTAL INTEGER )
Az utasts vgn nem szerepel DBMS zr jel, mert ez az egyes DBMS-eknl klnbz. Pldul az Oracle pontosvesszt (;) hasznl a mondatok lezrsra, a Sybase pedig a go szt. Ezrt a Java kdban nem szksges megadni, a driver automatikusan a mondat vgre teszi a megfelel jelet. Msik dolog, ami meg kell emltennk az SQL utastsokrl, azok formja. A CREATE TABLE mondatban a kulcsszavak nagybetvel s minden rsz kln sorban van rva. Az SQL nem kveteli ezt meg, ez a konvenci csak az olvashatsgot teszi knnyebb. Alapvet az SQL-ben, hogy a kulcsszavakban nem kis-nagybet rzkeny (case sensitive), gy pldul a SELECT szt brmilyen mdon le lehetett volna rni. Pldnak okrt a kt verzival korbbi teljesen megegyezik az SQL illeten: Az egyes DBMS-k klnbzek lehetnek a nvazonostsban. Pldul nhny DBMS megkveteli, hogy az oszlop s a tbla nevek pontosan megfeleljenek a CREATE TABLE utastsban megadottaknak, mg msok nem. A biztonsg kedvrt nagybett hasznlunk az azonostknl, mint pldul COFFEES s SUPPLIERS, mert gy definiltuk ket. Eddig ksz vagyunk az SQL utasts megrsval, amely ltrehozza a COFFEES nev tblt. Most tegyk idzjelek kz (ksztsnk Stringet), s nevezzk el ezt a String-et createTableCoffees-nek, gy ezt a vltozt fel tudjuk hasznlni a Java kdban. Amint lttuk, a DBMS nem foglalkozik a sortrsekkel, de a Java programozsi nyelvben az a String objektum, ami meghaladja az egy sort, nem fog lefordulni. Kvetkezskppen, amikor String-et adunk meg, minden egyes sort idzjelek kz kell tenni, s pluszjelet (+) hasznlni az sszefzshez:
String createTableCoffees = "CREATE TABLE COFFEES " + "(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " + "SALES INTEGER, TOTAL INTEGER)";
234. oldal
Egy mr l adatbzis kapcsolatra (Connection objektum) pl a Statement objektum ltrehozsra. A kvetkez plda a mr meglv con Connections objektumot hasznlja az stmt Statement objektum ltrehozsra:
Statement stmt = con.createStatement();
Ebben a pillanatban stmt ltrejtt, de mg nincs megadva az elkldend SQL utasts. Az stmt execute metdusban kell ezt megadnunk. Pldul, a kvetkez kdrszletben mi az executeUpdate metdusnak adjuk t a SQL utastst:
stmt.executeUpdate("CREATE TABLE COFFEES " + "(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " + "SALES INTEGER, TOTAL INTEGER)");
Miutn ltrehoztunk egy createTableCoffees nev String tpus vltozt, megadhatjuk ebben a formban is.
stmt.executeUpdate(createTableCoffees);
A kvetkez kd egy rekordot illeszt be: Colombian a COF_NAME oszlopba, 101 a SUP_ID oszlopba, 7.99 a PRICE, 0 a SALES s 0 a TOTAL oszlopba. (Amita a Coffee Break mkdik, a heti eladsi mennyisg s az eddigi sszmennyisg az sszes kvfajtnl 0-val indul.) Csakgy mint a COFFEES tbla ltrehozsnl tettk, egy Statement objektumot hozunk ltre, majd az executeUpdate metdust hasznljuk. Mivel az SQL utasts nem fr el egy sorba, kt String-et fogunk pluszjellel sszefzni. rdemes figyelni a szksges szkzkre a COFFEES s a VALUES sz kztt. A szkznek az aposztrfok kztt kell lennie vagy a COFFEES sz mgtt, vagy a VALUES sz eltt; a szkz nlkl az SQL utasts hibsan INSERT INTO COFFEESVALUES...nek fogja olvasni, s a DBMS a COFFEESVALUES nev tblt fogja keresni. Szintn oda kell figyelni, hogy egyszeres idzjelet hasznlunk a kv nevnek megadsakor, mert az kt dupla aposztrf kz van begyazva. A legtbb adatbzis-kezelnl ltalnos szably, hogy szabadon vlaszthat, melyik aposztrfot hasznljuk.
23.JDBC adatbzis-kezels
Statement stmt = con.createStatement(); stmt.executeUpdate( "INSERT INTO COFFEES " + "VALUES ('Colombian', 101, 7.99, 0, 0)");
235. oldal
Az INSERT utasts msodik sora fogja beilleszteni a rekordot a COFFEES tblba. Hasznljuk fel inkbb jra az stmt nev Statement objektumot, mint jat pldnyostsunk minden vgrehajtsnl.
stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES ('French_Roast', 49, 8.99, 0, 0)");
Az eredmny megegyezik azzal, amit az a kimenet ad, amikor az SQL lekrdezst direkt az adatbzis-kezelnek adjuk meg. Amikor egy Java alkalmazson keresztl rjk el az adatbzist, vissza kell, hogy nyerjk az adatokat, hogy felhasznlhassuk. A kvetkez rszben ezt mutatjuk be. Egy msik plda a SELECT utastsra, amelyik visszaadja a kvk listjt s az rat.
SELECT COF_NAME, PRICE FROM COFFEES
A lekrdezs eredmnye a kvetkez: A fenti SELECT utasts visszaadta az sszes rekordot, a kvetkez pedig csak azokat, amelyek kevesebbe kerlnek, mint $9.00
SELECT COF_NAME, PRICE FROM COFFEES WHERE PRICE < 9.00
236. oldal
A next metdus
Az eredmnyhalmaz elrhetv tev rs objektummal minden rekordon vgig fogunk menni, hogy az egyes rekordok adatait meg tudjuk jelenteni a kpernyn. A next metdus az gynevezett a kurzort mindig a kvetkez sorra mozgatja (ezt aktulis sornak hvjuk). Mivel a kurzor kezdetben mg nem mutat egyetlen sorra sem (mintha a tblzat eltt lennnk), az els meghvsa utn rhet el az eredmny els sora. Egymst kvet metdushvsokkal a kurzort a kvetkez rekordokra lptetjk, gy jrjuk be a teljes halmazt.
A getXXX metdusok
A get kezdet metdusok segtsgvel tudjuk az aktulis rekord egyes mezit lekrdezni. Pldul az SQL VARCHAR tpus COF_NAME mezjt a getString-el olvashatjuk ki. Az SQL FLOAT tpus PRICE mezje logikusan a getFloat metdussal krdezhet le. Nzzk a teljes kdot:
String query = "SELECT COF_NAME, PRICE FROM COFFEES"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String s = rs.getString("COF_NAME"); float n = rs.getFloat("PRICE"); System.out.println(s + " " + n); }
24.Kdolsi konvencik
237. oldal
24.Kdolsi konvencik
A kdolsi konvencik a kvetkezk miatt szksgesek: A szoftver letciklus kltsgnek 80%-a mehet el a karbantartsra A szoftvereknek csak kis rsztt tartja karban az eredeti fejleszt A kdolsi konvencik javtjk az olvashatsgot, segtve a ksbbi megrtst
Kezd megjegyzs
Minden forrsllomnynak kellene tartalmaznia egy C stlus megjegyzst a (publikus) osztly nevvel, verzi informciival, dtummal s szerzi jogokkal:
/* * Osztlynv * * Verzi informcik * * Dtum * * Copyright */
238. oldal
24.2. Behzs
Megjegyzs: Ebben a jegyzetben a nyomtats specilis trdelse miatt nhol eltrtnk a kvetkez szablyoktl.
2 vagy 4 szkz, vagy a tabultor karakter hasznlata clszer. A sorok hossza ne legyen tbb 80 karakternl. Bizonyos esetekben rdemes 70 karakterben maximlni a sor hosszt.
239. oldal
A kvetkez kt plda aritmetikai kifejezsek trsrl szl. Az els plda elfogadhat, a trs alkalmazkodik a logikai szerkezethez, de a msodik nem javasolt.
longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6; longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6;
A kvetkez kt kd metdusdeklarci bemutatsra szolgl. Az els a szoksos esetet mutatja, de a msodiknl ez nem mkdne. Ezrt ott a fix ktszeres behzst alkalmazzuk:
someMethod(int anArg, Object anotherArg, String yetAnotherArg, Object andStillAnother) { ... } private static synchronized horkingLongMethodName(int anArg, Object anotherArg, String yetAnotherArg, Object andStillAnother) { ... }
Az if utasts trse esetn is a dupla behzs javasolhat, az egyszeres behzs nehezebben felismerhetv teszi a trzset. Az els teht nem clszer, helyette a msodik vagy harmadik javasolhat:
if ((condition1 && condition2) || (condition3 && condition4) ||!(condition5 && condition6)) { doSomethingAboutIt(); } if ((condition1 && condition2) || (condition3 && condition4) ||!(condition5 && condition6)) { doSomethingAboutIt(); } if ((condition1 && condition2) || (condition3 && condition4) ||!(condition5 && condition6)) { doSomethingAboutIt(); }
240. oldal
24.3. Megjegyzsek
A Java programok ktfle megjegyzst alkalmaznak: dokumentcis s implementcis megjegyzst. Az utbbi a C++ nyelvhez hasonl, mg az elbbi a Java specialitsa. (Megjegyzs: Ezt a bevlt tletet a PHP is tvette.) A dokumentcis megjegyzs /** s */ kztti karaktersorozat. A javadoc segdprogram kpes ez alapjn automatikusan generlni HTML alap, teljesen hipertext felpts dokumentcit. A dokumentcis megjegyzs a forrskdot dokumentlja olyan megkzeltsben, hogy az alapjn a ksbbi megrts, az osztly felhasznlsa maradktalanul megoldhat legyen a kd kzzel trtn vgignzse nlkl is.
24.3.1
Implementcis megjegyzsek
Blokk megjegyzsek
A blokk megjegyzsek lerst tartalmaznak a fjlhoz, metdushoz, adatszerkezethez vagy algoritmushoz. Fjl esetn a fjl elejn, a tbbi esetben a metdus belsejben szoks elhelyezni, alkalmazkodva a megjegyzssel elltott egysg behzshoz. A blokk megjegyzs egy res sorral kezddik s fejezdik is be:
/* * Blokk megjegyzs. */
Egysoros megjegyzsek
A rvid megjegyzseket egyetlen sorba rva, a bekezdsi szintet figyelembe vve lehet elhelyezni. Ha nem lehet egy sorba rni, akkor blokk megjegyzst rdemes alkalmazni. Egy res sor utn rdemes rni a megjegyzst, hogy vizulisan lthatk legyenek az sszefggsek.
if (felttel) { /* Eset lersa. */ ...
Nyomkvetsi megjegyzsek
Nagyon rvid megjegyzseket az adott kdsor vgre is lehet rni, megfelel kzzel elvlasztva a kdtl. Clszer az egyms utni nyomkvetsi megjegyzseket azonos pozciban kezdeni. A kvetkez plda mutatja a hasznlat mdjt:
if (a % 2 == 0) { return TRUE; } else { return isPrime(a); } /* pros szm esetn ksz */ /* klnben vizsgljuk */
24.Kdolsi konvencik
241. oldal
Termszetesen alkalmazhat a // is, de csak kvetkezetesen, nem keverve a kt mdot. Nem rdemes olyan megjegyzseket alkalmazni, amik a ksbbi megrtst nem segtik el jelentsen.
Megjegyzs: A jegyzet pldi oktatsi clbl kszltek, sokszor tl rszletesen kommentezve. Valdi fejlesztskor csak a tnylegesen szksges megjegyzseket rdemes elhelyezni.
242. oldal
A legfels szint osztlyok s interfszek a sor elejn kezddnek, mg a tagok behzva. Az osztlyok s interfszek dokumentcis megjegyzsnek els sora nem behzott, a tovbbi sorok egy szkzzel bentebb kezddnek. Minden tag (osztly, interfsz, adattag, metdus, konstruktor) dokumentcis megjegyzsnek els sora 4 szkzzel, a tovbbiak 5 szkzzel bentebb kezddnek. A tovbbi szintek ugyangy, rtelemszeren.
24.4.Deklarcik
A knny kommentezhetsg (s a jobb tlthatsg) rdekben minden sor csak egy deklarcit tartalmaz:
int level; // indentation level int size; // size of table
Kevsb javasolhat:
int level, size;
A loklis vltozkat lehetleg mr a deklarcinl inicializljuk. Az egyetlen sszer kivtel, ha a kezdrtk bonyolult szmtsokkal fog elllni.
24.Kdolsi konvencik
243. oldal
rdemes elkerlni, hogy egy loklis deklarci elfedjen egy magasabb szint deklarcit:
int count; ... myMethod() { if (condition) { int count = 0; ... } ... }
// AVOID!
244. oldal
24.5. Utastsok
Egyszer utastsok
Soronknt csak egy utasts szerepel:
argv++; // Correct argc--; // Correct argv++; argc--; // AVOID!
sszetett utastsok
Az sszetett utasts { s } kztt utastsok sorozatt tartalmazza. A tartalmazott utastsok egy kzzel (4 szkzzel) bentebb kezddnek, mint az sszetett utasts blokk.
Feltteles utastsok
Az if, if-else, if else-if else utastsok:
if (condition) { statements; } if (condition) { statements; } else { statements; } if (condition) { statements; } else if (condition) { statements; } else{ statements; }
24.Kdolsi konvencik
switch (condition) { case ABC: statements; /* falls through */ case DEF: statements; break; case XYZ: statements; break; default: statements; break; }
245. oldal
Mindig rjuk ki a break utastst. Ha nem kell kilpni a case vgn, akkor megjegyzskn szerepeljen.
Ciklusutastsok
A for utasts formja a kvetkez:
for (initialization; condition; update) { statements; }
Amikor hasznljuk a , opertort az inicializl vagy a nvekmny rszben, akkor a kd nehezebben ttekinthet lesz. rdemes megfontolni, hogy ilyen esetben nem jobb-e az inicializcit a ciklus el rni. A szoksos s az res trzs while utasts formja:
while (condition) { statements; } while (condition);
A do-while formja:
do { statements; } while (condition);
try-catch utasts
try { statements; } catch (ExceptionClass e) { statements; }
246. oldal
try { statements; } catch (ExceptionClass e) { statements; } finally { statements; }
24.6.Elvlasztk
Az res sorok logikailag tagoljk, s gy olvashatbb teszik a kdot. Kt res sort alkalmazzunk osztlyok elvlasztsra. Egy sor elegend a kvetkez esetekben: Metdusok kztt Vltoz deklarcik s a blokk els utastsa kztt Blokk vagy egysoros megjegyzs eltt A metdus logikai egysgei kztt (jellemzen 3-10 soronknt) A kulcssz s a ( kztt:
while (true) { ... }
A paramterlistban vesszk utn A. kivtelvel minden binris opertor eltt s utn, unris opertorok esetn azonban nem alkalmazzuk:
a += c + d; a = (a + b) / (c * d); while (d++ = s++) { n++; } printSize("size is " + foo + "\n");
24.Kdolsi konvencik Azonost tpusa Csomag Szably Az egyedi csomagnv mindig csupa kisbetkbl ll. Az internet domn nv legfels szint eleme (pl. com, hu) utn a vllalat neve, majd szksg szerint tovbbi alcsomag-nevek kvetkeznek ponttal elvlasztva. Csak az angol abc beti hasznlhatk. Az osztlynv tbbnyire fnv, a kezdbet s a kztes szkezd betk nagybetk, a tbbi kisbet. Az alhzs karakter nem alkalmazhat. Ne legyen rvidts, mindig a teljes szavakat tartalmazza. Pldk com.sun.eng
247. oldal
com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese
Osztly
Interfsz
Lehet kezetes karaktereket is alkal- interface Storing; mazni, br ezt bizonyos fejlesztkrnyezetek (teht nem a Java!) nem engedik. Emiatt ltalban rdemes kerlni az kezetek hasznlatt. Metdus A metdus neve tbbnyire ige, a kztes run(); szavak kezdbeti kivtelvel minden runFast(); kisbets, a legels bet is. getBackground(); A vltoznevek rvidek, de beszdesek int i; legyenek. Az adott rvnyessgi tarto- float myWidth; mny brmelyik pontjn egyrtelm legyen a szerepe. Lehetleg kerljk az egy karakteres neveket, kivve a ciklusvltozk szoksos nevei (i, j, stb.). A kztes szavak kezdbeti kivtelvel minden kisbets, a legels bet is. Konstans A konstans vltozk neve csupa nagybe- static final int ts, a tbbszavas sszetteleket az _ MIN_WIDTH = 4; karakterrel kell elvlasztani. static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1;
Vltoz
248. oldal
25.Tervezsi mintk
Ebben a fejezetben alapos elmleti bevezetst nem tudunk adni, csupn nhny egyszer pldt ttekinteni van lehetsgnk. A tma sokkal alaposabb megrtshez Erich Gamma, Ralph Johnson, Richard Helm, John Vlissides: Programtervezsi mintk cm knyvt rdemes elvenni. (Letenni az OOP irnt rdekldk gysem tudjk :)
Mi a tervezsi minta?
Ha egy feladat jra elkerl a fejleszts folyamn, akkor valsznleg a megolds hasonl lesz a korbbihoz. A tervezsi mintk olyan objektumkzpont megoldsokat jelentenek, amelyek mr bizonytottak a gyakorlatban. Ezek felhasznlsa rugalmasabban mdosthat s knnyebben, jobban jrahasznosthat alkalmazsokat kszthetnk. A mintk lersra egysges mdszereket szoks alkalmazni. Ez lnyegt tekintve a kvetkezket tartalmazza: Motivci: mi volt az az eredeti problma, ami miatt a tma elkerlt. A rsztvevk s a struktra lersa. A hasznlat felttelei: meddig terjed a minta alkalmazhatsga. Tovbbi alkalmazsi pldk.
E jegyzetben terjedelmi okokbl csupn egy kevsb formlis, az rdeklds felkeltsre szolgl bevezett tudunk nyjtani. Bevezetsknt mg kvetkezzen egy ttekint tblzat: Cl Ltrehozsi Osztly Gyrtfggvny Szerkezeti (Osztly)illeszt Viselkedsi rtelmez Sablonfggvny Elvont gyr Hatkr pt Prototpus Objektum Egyke (Objektum)illeszt Hd sszettel Dszt Homlokzat Pehelysly Helyettes Felelssglnc Parancs Bejr Kzvett Emlkeztet Megfigyel llapot Stratgia Ltogat
25.Tervezsi mintk
249. oldal
25.1.1
Egyke (Singleton)
Az Egyke minta akkor hasznos, ha egy osztlybl csak egyetlen pldny ltrehozst szeretnnk engedlyezni. A mdszer lnyege, hogy kontrollljuk a pldnyostst egy privt konstruktor ltrehozsval. Az osztlybl csak egyetlen pldnyt hozunk ltre, azt is csak szksg (az els krs) esetn. A pldny elrse egy statikus gyrt metduson keresztl trtnik. Nzznk elszr egy ltalnos pldt:
class Singleton { private static Singleton instance = null; private Singleton() { } static public Singleton instance() { if (instance == null) { instance = new Singleton(); } return instance; } public void finalize() { instance = null; }
Ha egy jabb pldnyt krnk, akkor is ugyanazt az objektumot kapjuk. Hibs lenne viszont, ha kzvetlenl prblnnk pldnyostani:
Singleton one = new Singleton(); // hibs
Egy kicsit ms megoldst lthatunk egy tvoli kapcsolat kiptst megvalst osztlynl. Itt a kapcsolat mindig szksges, a duplikls elkerlse a f clunk.
Megjegyzs: rdemes belegondolni, milyen zavarokkal jrna, ha a programoz figyelmetlensge miatt egyszerre kt vagy tbb tvoli kapcsolatot prblnnk kipteni s hasznlni ugyanazon erforrs fel.
final class RemoteConnection { private Connect con; private static RemoteConnection rc = new RemoteConnection(connection);
250. oldal
private RemoteConnection(Connect c) { con = c; .... }
public static RemoteConnection getRemoteConnection() { return rc; } public void setConnection(Connect c) { this(c); } }
Szerzi megjegyzs: Tovbbi mintk bemutatsa tervben van.
25.1.2
A gyrtfggvny minta az egyik legtbbet alkalmazott tervezsi minta. A minta clja egy objektum ltrehozsa klnbz informcik alapjn. A kvetkez brn a bemeneti informcit az abc jelkpezi. Ez alapjn a gyrtfggvny az x sosztly valamelyik leszrmazottjt (xy vagy xz) fogja pldnyostani. A getClass hvsra ltrejv objektum tnyleges tpusrl tbbnyire nem is kell tudnia a felhasznlnak.
Nzznk egy konkrt pldt. A feladatunk az, hogy a nevek kezelse krli kvetkez problmt megoldjuk. Az angol nyelvben ktfle mdon is megadhatjuk ugyanazt a nevet: Jack London London, Jack
Ha egy beviteli mezben a felhasznl megadja a nevt, akkor brmelyiket hasznlja. Neknk az a feladatunk, hogy a nv alapjn egy olyan objektumot hozzuk ltre, amelyikbl brmikor elrhetk a szksges szolgltatsok. Elszr nzzk meg azt az sosztlyt, amelynek a szolgltatsaira vgs soron szksgnk lesz:
abstract class Namer { protected String last; protected String first; public String getFirst() { return first; }
25.Tervezsi mintk
public String getLast() { return last; }
251. oldal
Nzzk meg a kt igen egyszer leszrmazott osztlyt is. Az els leszrmazottunk a nv megadsnl az els ( szkzs) megadst felttelezi.
class FirstFirst extends Namer { public FirstFirst(String s) { int i = s.lastIndexOf(" "); if (i > 0) { first = s.substring(0, i).trim(); last =s.substring(i+1).trim(); } else { first = ""; last = s; } } }
Elegend a getNamer metdust a nevet tartalmaz String paramterrel meghvni, eredmnyl pedig egy Namer (leszrmazott) objektumot kapunk.
Megjegyezs: A plda lttn felmerlhet az a kifogs, hogy elegend lett volna a Namer osztly konstruktorban ezt a ktfle inputot megklnbzteti. Ennl a pldnl tnyleg jrhat lenne ez az t is. A plda egyszersge abban rejlik, hogy a leszrmazottak csak a konstruktorunkban trnek el egymstl. Ms sszetettebb szituci esetn a leszrmazottak rdemi mkdse is jelentsen eltrhet egymstl. Legersebb rvknt pedig azt rdemes meggondolni, hogy ha a bemutatott struktrt kell bvtennk egy jfajta viselkedssel, akkor elegend egy j leszrmazott osztly ltrehozsa s a getNamer metdus bvtse, a tbbi osztlyhoz egyltaln nem kell hozznylni. Ez egy nagyobb alkalmazs esetn nagyon erteljes rv lehet.
252. oldal
26.Java fejleszteszkzk
253. oldal
26.Java fejleszteszkzk
Brmelyik fejleszteszkzt is vlasztjuk, teleptsk elszr a fejlesztkrnyezetet s a dokumentcit az 1.1 fejezetben lert mdon.
26.1. JCreator
A JCreator Java programozsra alkalmas editor. A program letlthet a http://www.jcreator.com/download.htm cmrl. A Pro vltozat 30 napig mkd dem, de letlthet a korltlan ideig hasznlhat (freeware), br nmileg kevesebb tuds Lite Edition vltozat is.
26.2. Netbeans
A Netbeans a Sun sajt fejlesztkrnyezete a Java platformokhoz. A J2SE vltozattal kzs csomagban is letlthetjk, gy a telepts is nagyon egyszer lesz. (A kzs csomag a Sun honlapjrl tlthet le.) A http://www.netbeans.org/ cmrl nem csak az alapcsomagot, hanem klnbz szszelltsokat s kiegsztket is letlthetnk. Ha nem a J2SE-vel kzs csomagot teleptjk, akkor (a JCreatorhoz hasonlan) a Netbeanst rdemes ksbb telepteni.
254. oldal
26.2.1
Alapvet hasznlat
Projekt ltrehozsa
A Netbeans indtsa utn File > New Project:
Egy alapvet Java projekthez a General csoport Java Application eleme alkalmas.
Kvetkez lpsknt a projekt nevt s elrsi tjt kell megadnunk. (A projekt alkalmas arra, hogy egy tbb osztlybl ll alkalmazs forrsllomnyit egy egysgknt kezeljk.) Bellthatjuk projektnket elsdlegesnek (Main project), s megadhatjuk a f osztlyunk nevt is:
26.Java fejleszteszkzk
255. oldal
256. oldal
26.3. Eclipse
Az Eclipse egy tbb platformon (Windows mellett Linux, Solaris, AIX, HP-UX, Mac OSX) rendelkezsre ll, tbb programozsi nyelvet (Java, PHP, C/C++, stb.) tmogat s tbbfajta fejleszti krnyezetben (asztali alkalmazsfejleszts, webfejleszts, mobil alkalmazsfejleszts, UML2 szerkeszts, vizulis szerkeszts stb.) alkalmazhat nylt forrs szoftverfejleszt projekt.
26.3.1
Alap tulajdonsgok
Az Eclipse egy teljesen a felhasznl ignye szerint kialakthat fellettel rendelkezik (melyet perspektvnak hvnak), egyszer (fogd s vidd) felleten tpakolhatjuk a megnyitott ablakokat (nzeteket). Tbb felletet is kialakthatunk magunknak az ppen aktulis munktl fggen (programozs, HTML szerkeszts, stb.), melyek kztt a rendszer automatikusan is tud vltani, illetve mi is vltogathatunk. Szmos nzet ll rendelkezsnkre alapkiptsben, illetve ezek listja bepl modulokkal tovbb bvthet. Ilyen a szerkesztmez s a projekt fjlok listja (navigator) mellett a problmk, tennivalk listja, a kivonat doboz (az aktulis llomny vza: XML szerkezet, vagy a fggvnyek listja, stb.). A beptett szerkeszt fleg Java s kapcsold kdsznezseket tmogat, de ezt a Colorer plugin2 segtsgvel kiegszthetjk: gy rengeteg nyelv ll rendelkezsnkre, illetve ha nem tallunk egyet, XML lerk segtsgvel kibvthetjk a rendszert.
http://colorer.sourceforge.net/
26.Java fejleszteszkzk
257. oldal
258. oldal