Java
- Osnovni kurs -
Sadržaj:
Istorija i osnovne karakteristike programskog jezika Java .............................................................3
Objašnjavanje pojma, koncepta i osnovih principa objektno orijentisanog programiranja.............3
Dizajn jezika Java............................................................................................................................4
Java Virtuelna Mašina.....................................................................................................................7
Java izvorni kod...............................................................................................................................8
Java Development KIT....................................................................................................................9
Prvi jednostavan primer na programskom jeziku Java..................................................................10
Naredbe..........................................................................................................................................12
Komentari u Java programima.......................................................................................................12
Java ključne i rezervisane reči.......................................................................................................12
Literali............................................................................................................................................13
Promenljive i tipovi podataka........................................................................................................17
Kontrolne strukture........................................................................................................................25
Operatori........................................................................................................................................31
Iteracija (ciklusi, petlje).................................................................................................................36
While petlja....................................................................................................................................37
Do-while petlja...............................................................................................................................38
For petlja........................................................................................................................................39
Kontrolne naredbe skoka – break i continue..................................................................................43
Korišćenje labela............................................................................................................................45
Java klase.......................................................................................................................................47
Deklaracije polja............................................................................................................................47
Pristup polju...................................................................................................................................48
Postavljanje inicijalnih vrednosti...................................................................................................49
Statički članovi...............................................................................................................................50
Metodi-članovi...............................................................................................................................50
Preopterećenoi metodi...................................................................................................................52
Konstruktori...................................................................................................................................53
Promenljiva this.............................................................................................................................55
Rekurzija........................................................................................................................................57
Nasleđivanje klasa.........................................................................................................................58
Kontrola pristupa...........................................................................................................................59
Rezervisana reč super....................................................................................................................59
Redefinisanje metoda.....................................................................................................................59
Apstraktne klase.............................................................................................................................61
Rezerviasna reč final......................................................................................................................62
Klasa Object...................................................................................................................................64
Paketi..............................................................................................................................................65
Uvoženje paketa.............................................................................................................................66
1
Interfejsi.........................................................................................................................................67
Izuzeci............................................................................................................................................69
Tipovi izuzetaka.............................................................................................................................70
Neuhvaćeni izuzeci........................................................................................................................70
Korišćenje try i catch.....................................................................................................................70
Prikaz opisa izuzetka......................................................................................................................71
Više odredaba catch.......................................................................................................................72
Ugnježdena naredba try.................................................................................................................74
Rezervisana reč throw....................................................................................................................75
Naredba throws..............................................................................................................................76
Rezervisana reč finally...................................................................................................................76
Javini ugrađeni izuzeci...................................................................................................................76
Pravljenje sopstvenih izuzetaka.....................................................................................................78
Javine kolekcije..............................................................................................................................79
Interfejs Collection.........................................................................................................................79
Interfejs List...................................................................................................................................81
Klasa ArrayList..............................................................................................................................81
Pristupanje kolekciji pomoću iteratora..........................................................................................81
For-each kao alternativa iteratorima..............................................................................................82
Apleti..............................................................................................................................................83
Obrada slika...................................................................................................................................84
Korišćenje kontrolnih objekata......................................................................................................85
Obrada događaja............................................................................................................................86
Klase događaja...............................................................................................................................87
Interfejsi prijemnika događaja.......................................................................................................87
2
Istorija i osnovne karakteristike programskog jezika Java
Java je jednostavan, objektno-orijentisan, robustan, siguran, portabilan, arhitektonski neutralan,
interpretiran, višenitni, dinamičan, programski jezik visokih performansi, koji je razvila
kompanija Sun Microsystems početkom devedesetih godina XX veka. Danas je to usavršeni
jezik za programiranje koji je postao neizbežan za programe koje je potrebno koristiti na
različitim kompjuterskim sistemima.
1991. godine James Gosling, Patrick Naughton i Mike Sheridan počinju projekat Green OS
1994. američka firma Sun Microsystems izdaje novi jezik baziran na Green OS programskom
jeziku OAK
1995. Sun izdaje prvu verziju jezika Java
Maj 2007. Sun je omogućio da najveći deo Java tehnologija bude besplatan (free software) pod
GNU licencom (The GNU General Public License).
-Poslednja izdata verzija Jave je Java Standard Edition 6.
Java između ostalog omogućava pisanje malih programa (takozvanih apleta) koji se mogu
ugraditi u web stranice da bi se obezbedile neke funkcionalnosti. Ipak, najvažnija karakteristika
Jave je da je dizajnirana tako da bude nezavisna od mašine, tj. računara. Java programi se mogu
koristiti neizmenjeni na svakom računaru koji podržava Javu.
Objašnjavanje pojma, koncepta i osnovih principa objektno orijentisanog
programiranja
Sledeća vrlo važna karakteristika Jave je da je to objektno-orijentisani programski jezik.
Objektno-orijentisano programiranje je paradigma programiranja, koja koristi objekte kao
osnovu za projektovanje računarskih programa i različitih aplikacija softvera. Osnovni principi
objektno-orijentisanog programiranja su:
•
•
•
•
nasleđivanje
modularnost
polimorfizam
enkapsulacija.
Rešavanje problema paradigmom objektno-orijentisanog programiranja, je vrlo slično ljudskom
načinu razmišljanja i rešavanju problema. Sastoji se od identifikovanja objekata i postavljanja
objekata koji će se koristiti, u odgovarajuću sekvencu za rešenje određenog problema. Radi se o
dizajnu objekata čija će ponašanja kao jedinica i u njihovoj međusobnoj interakciji, rešiti
3
određeni problem. Interakcija između objekata se sastoji u razmeni poruka, gde određena poruka
usmerena prema određenom objektu, pokreće enkapsulirane operacije u tom objektu, čime se
rešava deo obično šireg i složenijeg problema. Uopšteno gledano, objektno-orijentisano
rešavanje problema se sastoji iz četiri koraka:
1.
2.
3.
4.
identifikovanje problema
identifikovanje objekata koji su potrebni za njegovo rešenje
identifikovanje poruka koje će objekti međusobno slati i primati
kreiranje sekvence poruka objektima, koje će rešavati problem ili probleme.
U paradigmi objektno-orijentisanog programiranja, objekti su strukture podataka koje
predstavljaju određeno i jasno definisano znanje o spoljašnjem svetu ili stvarnosti. Tipična
organizacija je u hijerarhijske klase, gde svaka klasa objekta poseduje informacije o osobinama
objekta koje se čuvaju u instancama promenljivih i koje su povezane (konceptom asocijacije) sa
svakom instancom u određenoj klasi. Svaki objekat prepoznaje drugi objekat preko njegovog
interfejsa. Podaci i logika svakog objekta su skriveni od drugih objekata. Time se omogućava
razdvajanje implementacije od ponašanja objekta u interakciji sa drugim objektima.
Dizajn jezika Java
Pre nego što kreiramo applet ili program u Javi, važno je da se shvati kako Java radi.
Java ima sledeće osobine:
•
•
•
•
je i kompajlirana i interpretirana
videćemo način i kompilacije i interpretiranja Jave i kako tako definisani procesi
kompajliranja i interpretacije utiču na brzinu Jave i na njenu nezavisnost od platformi.
izvršava se korišćenjem Java Virtualne Mašine
istražićemo dizajn Java Virtualne Mašine, kako ona radi tokom izvršavanja Java
programa i kao to utiče na nas. Takođe će biti reči i o sigurnosti koju obezbeđuje Java
virtuelna mašina.
je objektno-orijentisan jezik
naučićemo kako funkcionišu strukture klasa i kako se (i zašto) klase proširuju.
koristi Java API
tj. već je kreiran skup klasa raspoloživih programeru za korišćenje i njihov naziv je Java
API. Naučićemo kako da se koristi Java API u programiranju.
4
Java je kompajlirana pa interpretirana
Programer prvo kompajlira Java izvorni kod korišćenjem Java kompajlera u tzv. bajt-kod.
Kreirani bajt-kod je binaran i arhitektonski neutralan (često se koristi i termin platformski
neutralan). Bajt-kod nije kompletan sve dok se ne interpretira od strane Java runtime okruženja.
S obzirom na to da Java izvršno okruženje postoji posebno za svaku specifičnu platformu,
završni proizvod će raditi na toj specifičnoj platformi.
Dakle, Java izvorni kod ostaje Java kod bez obzira na kojoj se platformi izvršava. Java aplet se,
prema tome, može napisati i kompajlirati na UNIX sistemu i potom ubaciti taj aplet u web
stranu. Korišćenjem Jave se postiže da samo jedan izvorni Java kod treba da se održava a
program će raditi na različitim platformama.
5
S obzirom na to da se Java bajt-kod interpretira, Web strane sa apletima se obično učitavaju i
prikazuju duže od klasičnih (statičnih). Naime, zajedno sa stranom se dovlači na klijentski sistem
i bajt-kod (slično kao što se dovlače statične slike koje se nalaze na HTML stranama). Potom
serija procedura proverava sigurnost apleta, tj. njegovu robusnost. Javina prenosivost je skoro
neograničena, što je postignuto po cenu gubitka performansi.
Gubitak performansi je smanjen korišćenjem Just-in-Time (srp. «u pravo vreme») ili JIT
kompajlera. JIT kompajler prevodi Java metode u mašinski kod za konkretnu platformu na kojoj
se koristi. Na ovaj način Java ostaje portabilna, ali JIT kompajler nije.
Zašto je kombinacija kompilacije i interpretacije pozitivna osobina?
•
•
obezbeđuje sigurnost i stabilnost. Java okruženje sadrži elemenat nazvan linker, koji
proverava podatke koji dolaze na mašinu kako bi se uverila da oni ne sadrže delove koji
bi mogli oštetiti fajlove (sigurnost) ili na drugi način onesposobiti rad sistema
(robusnost).
ova kombinacija kompilacije i interpretiranja razrešava probleme neuklapanja verzija.
Java je objektno orijentisana
Java je objektno-orjentisan jezik (OOP jezik). Ona je, dakle, član familije jezika koji se
fokusiraju na definisanje podataka kao objekata i metoda koji mogu biti primenjeni na te objekte.
Java (kao i drugi OOP jezici) opisuju interakciju između objekata.
Mnogi OOP jezici podržavaju višestruko nasleđivanje, što ponekad dovodi da konfuzije ili
nepotrebnih komplikacija. Java je dizajnirana tako da podržava samo jednostruko nasleđivanje.
Ovo znači da data klasa može naslediti samo jednu klasu. Ovakvo nasleđivanje izbegava
probleme koji nastaju pri nasleđivanju dve klase čije je ponašanje kontradiktorno ili koje su
međusobno isključive.
6
Java dopušta i kreiranje totalno apstraktnih klasa, koje su poznate kao interfejsi. Interfejsi
dopuštaju kreiranje metoda koji mogu biti podeljeni između različitih klasa, bez obzira na to
kako ostale klase realizuju metode. Iako Java isključivo podržava jednostruko nasleđivanje, ona
ipak dopušta da klasa implementira više od jednog interfejsa.
Svaka klasa, bilo apstraktna ili ne, definiše ponašanje objekta (objekat je elemenat, član, instanca
klase) kroz skup metoda. Sav Java kod je podeljen u klase. Metodi mogu biti nasleđeni sa jedne
klase u drugu, a na vrhu klase hijerarhije se nalazi klasa nazvana Object. Klase Object pripada
paketu java.lang iz Java API-a. O Java API-ju će kasnije biti više reči.
Važno je zapamtiti da je Java striktno objektno orjentisan; on jednostavno ne dopušta da se
deklariše bilo šta što nije enkapsulirano (učaureno) u objekat.
Java Virtuelna Mašina
Srce Jave je JVM (Java Virtual Machine). JVM je virtualni računar koji postoji samo u
memoriji. JVM dopušta da Java programi budu izvršavani na raznovrsnim platformama (a ne
samo na onoj na kojoj je izvršena kompilacija). Da bi Java programi mogli da rade na odreženoj
platformi, mora JVM da bude implementirana na toj platformi.
JVM je glavni razlog prenosivosti (portabilnosti) Jave, koji obezbeđuje dodatni nivo apstarkcije
između kompajliranog Java programa i hardverske platforme i operativnog sistema koji se nalaze
ispod.
7
Java izvorni kod
Java izvorni kod se kompajlira na nivo bajt-koda, a ne bit-koda. JVM izvršava bajt-kod. Program
javac, tj. Java kompajler, čita fajlove sa ekstenzijom .java, konvertuje kod iz .java fajla u bajtkod, i rezultujući bajt-kod čuva u fajlu sa ekstenzijom .class.
JVM čita tok bajt-kodova iz .class fajla kao sekvencu instrukcija. Svaka od instrukcija se sastoji
od jednobajtnog opkod-a, koji predstavlja specifičnu i prepoznatljivu komandu i od nula, jednog
ili više operanada (podataka potrebnih za kompletiranje instrukcije). Opkod govori šta JVM
treba da uradi. Ako JVM zahteva operande za izvršenje operacije, tada operandi slede
neposredno iza opkod-a.
JVM se sastoji od sledećih delova:
8
Java stek
Java registri
Prostor i prikupljanje đubreta
Java API
Centralni Java API
Java Enterprise API
Java Commerce API
Java Server API
Java Media API
Java Security API
Java Beans API
Java Embedded API
Java Development Kit
Razlog velike popularnosti jezika Java je, pored kvaliteta njenog dizajna, i činjenica da je uz
Javu priključen (kao JDK) i bogat set paketa (u drugim jezicima biblioteka klasa). Ovi već
oformljeni objekti omogućavaju brz start pri radu sa Javom, iz dva razloga:
•
•
programer ne mora ponovo da razvija njihovu funkcionalnost.
Izvorni kod je svima dostupan.
Kratak pregled najznačajnijih paketa koji dolaze sa Javom:
•
•
•
•
•
•
•
Klase za razvoj apleta.
Abstract Window Toolkit (AWT) klase za GUI kao što su prozori, dijalozi, dugmići,
tekstualna polja, itd.
Klase za mreže, URL-ova, klijent-serverske sokete.
Klase za različite tipove ulaza i izlaza.
Klase za različite tipove podataka, procese koji se izvršavaju, niske znakova, niti, itd.
Pomoćne klase za datume, vektore itd.
Klase za manipulaciju slikama.
9
Prvi jednostavan primer na programskom jeziku Java
Nasa prva aplikacija ce biti vrlo jednostavna. Program ce demonstrirati izlazne funkcije Jave
tako sto ce na ekran ispisivati poruku “Zdravo svete!” Nakon sto ukucamo program, fajl cemo
sacuvati pod imenom ZdravoSvete.java. Program sadrzi jednostavnu klasu, a Java kompajler
ocekuje da se ime fajla poklapa sa imenom klase.
Struktura programa je sledeća:
public class program-name {
opciono deklaracija promenjivih i metoda
public static void main(String[] args) {
izrazi
}
opciono deklaracija promenjivih i metoda
}
Kod izgleda ovako:
10
/** Komentar
* Ispisuje "Hello World!" na standardni izlaz.
*/
class ZdravoSvete {
public static void main (String args[]) {
System.out.println("Zdravo Svete!"); //Ispisuje navedeni tekst
}
}
Za kompajliranje java koda potreban nam je “javac” alat. Iz komandne linije, naredba koja
pokreće kompajliranje programa je:
javac ZdravoSvete.java
Ako je kompilacija uspešno prošla, “javac” će završiti sa radom i vratiti nam komandni prompt.
Ako pogledamo u direktorijum u kojem smo napisali program, u njemu ce se nalaziti fajl koji se
zove ZdravoSvete.class. Ovaj fajl je zapravo kompajlirana verzija našeg programa. Kada je
program u ovom obliku, spreman je za izvršavanje. Sada smo spremni da pokrenemo naš prvi
program, a to ćemo uraditi pokretanjem komande:
java ZdravoSvete
11
Naredbe
U programiranju, naredba se može shvatiti kao najmanji zasebni element imperativnog
programskog jezika. Program je oblikovan kao niz jedne ili više naredbi. Vrste naredbi su:
•
•
•
•
deklaracije: tip promenjiva;
definicije: tip promenjiva = vrednost;
jednostavne naredbe (dodela, poziv, povratak…)
složene naredbe (blokovi naredbi – if, switch, petlje…)
Komentari u Java programima
Postoje tri vrste komentara u programskom jeziku Java:
/* text */
Kompajler ignoriše sve od znakova /*do znakova */.
/** dokumentacija */
Ovo ukazuje na dokumentacioni komentar (doc comment, skraćeno). Kompajler ignoriše ovu
vrstu komentara na isti način kao i komentare koji se nalaze između /*i */. Međutim, JDK
javadoc alat koristi ove komentare kada priprema automatski generisanu dokumentaciju.
// text
Kompajer ignoriše sve od tog znaka do kraja reda.
Java ključne i rezervisane reči
Tabela koja sledi prikazuje sve Java ključne reči:
abstract
Ključne Java reči
float
public
boolean
for
return
break
if
short
byte
implements
static
case
import
super
catch
instanceof
switch
char
int
synchronized
class
interface
this
continue
long
throw
12
default
native
throws
do
new
transient
double
null
try
else
operator
void
extends
package
volatile
final
private
while
finally
protected
Nadalje, Java specifikacija je rezervisala dodatne reči koje mogu biti iskorišćene u budućnosti,
iako za sada nisu deo specifikacije. Sledeća tabela ukazuje na rezervisane reči koje zasad nisu
iskorišćene:
byvalue
Rezervisane Java reči
generic
outer
cast
goto
rest
const
inner
var
future
operator
Napomena
Uočava se da true i false nisu na spisku Java rezervisanih reči. One su u
stvari logički literali, mada se mogu posmatrati kao rezervisane reči.
Literali
Literal je eksplicitno napisana vrednost koja se koristi u programu. Na primer, program kome je
neophodna vrednost pi za izračunavanje može uključiti literal 3.1415, ili neki drugi program
može uključiti 65 kao broj godina neophodan za starosnu penziju. U oba ova slučaja 3.1415 i 65
su literali.
Celobrojni literali
Celobrojni literali mogu biti specificirani u dekadnoj, heksadekadnoj ili oktalnoj notaciji. Za
specifikaciju dekadne vrednosti, koristi se broj napisan na normalan način. Za ukazivanje da
literal predstavlja long vrednost, koristi se sufiks L ili l. Heksadekadni (ili heksadecimalni)
brojevi imaju osnovu sistema 16 i cifre 0-9 i A-F. Za specifikaciju heksadekadnih vrednosti
koristi se prefiks 0x. Na sličan način, prefiks 0 kod celobrojnog literala ukazuje da se radi o
oktalnoj vrednosti.
13
Tabela koja sledi prikazuje neke primere celobrojnih literala.
Dekadni
Integer
Primeri celobrojnih literala
Dekadni Long
Oktalni
Heksadecimalni
Integer
Integer
0
0L
0
0x0
1
1L
01
0x1
10
10L
012
0xA
15
15L
017
0XF
16
16L
020
0x10
100
100L
0144
0x64
Literali u pokretnom zarezu
Literali u pokretnom zarezu kod Jave su slični celobrojnim literalima. Ovi literali mogu biti
specificirani u decimalnoj notaciji (na primer, 3.1415) ili eksponencionalnoj (ponegde se još
naziva naučna) notaciji (na primer, 6.02e23). Sufiks tj. dopisivanje simbola f ili F indicira da
literal treba biti tretiran kao broj u pokretnom zarezu jednostruke tačnosti, dok sufiks d ili D
ukazuje da literal u pokretnom zarezu treba tumačiti kao broj dvostruke tačnosti.
Java uključuje i predefinisane konstante POSITIVE_INFINITY, NEGATIVE_INFINITY i NaN,
koje reprezentuju vrednosti pozitivne beskonačnosti, negativne beskonačnosti i “nije broj”,
respektivno.
Sledeći spisak sadrži korektne literale u pokretnom zarezu:
43.3F
3.1415d
-12.123f
6.02e+23f
6.02e23d
6.02e-23f
6.02e23d
Logički literali
14
Java podržava dva logička literala – true (eng. tačno, istina) i false (neistina, laž).
Znakovni literali
Znakovni literal je jedan karakter ili escape sekvenca (srp. sekvenca iskakanja), uokvirena
apostrofima (na primer, 'b'). Escape sekvence se koriste da označe specijalne znake ili akcije, kao
što su kraj linije (eng. line feed), kraj strane (eng. form feed) i povratak na početak (eng. carriage
return). Sledi primer nekoliko znakovnih literala i opis svih raspoloživih escape sekvenci.
'b'
'\n'
'\u15e'
'\t'
Escape sekvence
Sekvenca
Svrha
\b
Povratak za jedno mesto (backspace)
\t
Horizontalni tab
\n
Kraj linije (line feed)
\f
Kraj strane (form feed)
\r
Povratak na početak (carriage return)
\"
Navodnik (double quote)
\'
Apostrof (single quote)
\\
Obrnuta kosa crta (backslash)
\uxxxx
Unicode znak
String literali
Iako string (srp. niska) tip nije prost Java tip u Javi, string literali mogu da budu uključeni u
program. Najveći broj aplikacija i apleta će koristiti string literale, ako ni zbog čega drugog, ono
za poruke o greškama. String literal se sastoji od nula, jednog ili više znakova uokvirenih
navodnicima. Sledi nekoliko primera string literala:
"Jedna Niska"
"Kolona 1\tKolona 2"
"Prva linija\r\nDruga linija"
"Prva strana\fDruga strana"
""
15
S obzirom na to da Java nema prosti string tip, svako korišćenje string literala dovodi do toga da
se u pozadini kreira objekat klase String.
16
Promenljive i tipovi podataka
U programiranju, varijabla ili promenljiva (kako se češće naziva) označava imenovanu
memorijsku lokaciju koja se koristi za smeštanje određenog podatka. Tip promenljive određuje
kakav tip podatka data promenljiva može sadržati. Ime koje izaberemo za promenljivu zove se
identifikator. Za imena promenljivih ne smemo koristiti ključne reči.
Prosti tipovi su gradivni blokovi dela jezika koji se odnosi na podatke. Složeniji tipovi se prave
kombinovanjem prostih tipova Java jezika. Java jezik sadrži samo mali skup prostih tipova:
celobrojni tip, broj u pokretnom zarezu, karakterski i logički tip.
U Javi se promenljiva deklariše tako što se prvo napiše njen tip, iza koga sledi njegovo ime, kao
u sledećem primeru:
int x;
float minBrzina;
short ljudi;
long vremeDoSusreta;
double iznosZaduzen, iznosPlacen;
Jedine promenjive u Javi koje nisu objekti jesu promenljive koje odgovaraju jednom od osam
tipova podataka, definisanih unutar jezika. Ti tipovi podataka se nazivaju osnovni (ili prosti).
Celobrojni tipovi
Java sadrži četiri celobrojna tipa: byte, short, int, i long, koji su definisani kao 8-, 16-, 32-, i 64bitni označeni brojevi.
Tip
Java celobrojni prosti tipovi
Minimalna vrednost
Maksimalna vrednost
Bitovi
byte 8
-256
255
short 16
-32,768
32,767
int
-2,147,483,648
2,147,483,647
-9,223,372,036,854,775,808
9,223,372,036,854,775,807
32
long 64
Sledeća tabela prikazuje operacije koje se mogu izvršavati nad celim prostim brojevima.
Operacije nad celobrojnim vrednostima
Operator
Operacija
=
Jednakost
17
!=
Nejdnakost
>
Veće od
<
Manje od
>=
Veće ili jednako od
<=
Manje ili jednako od
+
Sabiranje
-
Oduzimanje
*
Množenje
/
Deljenje
%
Ostatak pri deljenju
++
Inkrementiranje
--
Dekrementiranje
~
Bitovna negacija (NOT)
&
Bitovna konjukcija (AND)
|
Bitovna disjunkcija (OR)
^
Bitovna ekskluzivna disjunkcija (XOR)
<<
Pomeranje (šiftovanje) ulevo
>>
Pomeranje (šiftovanje) udesno
>>>
Pomeranje (šiftovanje) udesno sa nulama
Ako je bar jedan od operatora tipa long, tada je rezultat operacije 64-bitni long. Ako jedan
operand nije long, taj će biti konvertovan u long pre izvršenja operacije. Ako nijedan od
operanada nije long, tada će operator biti izvršavan sa 32-bitnom preciznošću tipa int. Ma koji
operand tipa byte ili short će biti pretvoren u int pre izvršenja operacije.
Napomena
U jeziku Java se ne može vršiti pretvaranje između tipova boolean i int.
PRIMERI:
/* Java byte primer */
public class JavaByteExample {
public static void main(String[] args) {
byte b1 = 100;
18
byte b2 = 20;
System.out.println("Vrednost byte promenljive b1 je:" + b1);
System.out.println("Vrednost byte promenljive b2 je:" + b2);
}
}
/*
Izlaz programa će biti:
Vrednost byte promenljive b1 je:100
Vrednost byte promenljive b2 je:20
*/
/* Java int primer */
public class JavaIntExamples {
public static void main(String[] args) {
int i = 0;
int j = 100;
System.out.println("Vrednost int promenljive i je:" + i);
System.out.println("Vrednost int promenljive j je:" + j);
}
}
/*
Izlaz programa će biti:
Vrednost int promenljive i je:0
Vrednost int promenljive j je:100
*/
/* Java long Example */
import java.util.*;
public class JavaLongExample {
public static void main(String[] args) {
long timeInMilliseconds = new Date().getTime();
System.out.println("Vreme u milisekundama je: " + timeInMilliseconds);
}
}
19
/*
Izlaz programa će biti:
Vreme u milisekundama je: 1226836372234
*/
/* Java short primer */
public class JavaShortExample {
public static void main(String[] args) {
short s1 = 50;
short s2 = 42;
System.out.println("Vrednost short promenljive s1 je:" + s1);
System.out.println("Vrednost short promenljive s2 je:" + s2);
}
}
/*
Izlaz programa će biti:
Vrednost short promenljive s1 je:50
Vrednost short promenljive s2 je:42
*/
Tipovi u pokretnom zarezu
Podrška za dva tipa u pokretnom zarezu u jeziku Java je obezbeđeno kroz dva primitivna tipa:
float i double, koje su 32- i 64-bitne vrednosti, respektivno. Operatori koji su na raspolaganju za
ova dva primitivna tipa su dati sledećom tabelom.
Operatori nad vrednostima u pokretnom zarezu
Operator
Operacija
=
Jednakost
!=
Nejednakost
>
Veće od
<
Manje od
>=
Veće ili jednako od
<=
Manje ili jednako od
+
Sabiranje
-
Oduzimanje
*
Množenje
20
/
Deljenje
%
Ostatak pri deljenju
++
Inkrementiranje
--
Dekrementiranje
Java promenljive tipa float i double mogu biti pretvorene u druge numeričke tipove ali ne mogu
biti pretvoreni u tip boolean.
Brojevi u pokretnom zarezu mogu preuzeti ma koju od sledećih vrednosti:
•
•
•
•
•
•
•
Negativna beskonačnost
Negativna konačna vrednost
Negativna nula
Pozitivna nula
Pozitivna konačna vrednost
Pozitivna beskonačnost
NaN, ili «nije broj» (eng. «not a number»)
/* Java double primer */
public class JavaDoubleExample {
public static void main(String[] args) {
double d = 1232.44;
System.out.println("Vrednost double promenljive d je:" + d);
}
}
/*
Izlaz programa će biti:
Vrednost double promenljive d je:1232.44
*/
/* Java float primer */
import java.util.*;
public class JavaFloatExample {
public static void main(String[] args) {
float f = 10.4f;
System.out.println("Vrednost float promenljive f je:" + f);
}
21
}
/*
Izlaz programa će biti:
Vrednost float promenljive f je:10.4
*/
Ostali prosti tipovi
Pored celih brojeva i brojeva u pokretnom zarezu, Java sadrži još dva dodatna prosta tipa –
logički i znakovni. Promenljive tipa boolean (tj. logičke promenljive) mogu imati vrednost true
ili false, dok promenljive tipa char sadrže jedan unikod karakter.
Napomena
Java logička promenjiva nema vrednost 1 ili 0 - kao što je to u nekim drugim
jezicima, konkretno u C-u i C++-u.
/* Java boolean primer */
public class JavaBooleanExample {
public static void main(String[] args) {
boolean b1 = true;
boolean b2 = false;
boolean b3 = (10 > 2)? true:false;
System.out.println("Vrednost boolean promenljive b1 je :" + b1);
System.out.println("Vrednost boolean promenljive b2 je :" + b2);
System.out.println("Vrednost boolean promenljive b3 je :" + b3);
}
}
/*
Izlaz programa će biti:
Vrednost boolean promenljive b1 je :true
Vrednost boolean promenljive b2 je :false
Vrednost boolean promenljive b3 je :true
*/
/* Java char primer */
public class JavaCharExample {
22
public static void main(String[] args) {
char ch1 = 'a';
char ch2 = 65; /* ASCII code of 'A'*/
System.out.println("Vrednost char promenljive ch1 je:" + ch1);
System.out.println("Vrednost char promenljive ch2 je:" + ch2);
}
}
/*
Izlaz programa će biti:
Vrednost char promenljive ch1 je:a
Vrednost char promenljive ch1 je:A
*/
Podrazumevane vrednosti
Jedan čest uzrok pogramerskih grešaka je korišćenje neinicijalizovanih promenljivih.
Neinicijalizovana promenljiva može uzeti ma koju vrednost koja se ranije nalazila u memorijskoj
lokaciji koja odgovara toj promenljivoj. Java pomaže u razrešavanju problema neinicijalizovanih
promenljivih time što svakoj neinicijalizovanoj promenljivoj dodeljuje podrazumevanu (eng.
default) vrednost. Spisak podrazumevanih vrednosti je dat sledećom tabelom.
Standardne podrazumevane vrednosti za Java primitivne tipove
Tip
Podrazumevana vrednost
Byte
0
Short
0
Int
0
Long
0L
Float
0.0f
double
0.0d
Char
Null
boolean
False
all references
Null
Napomena
Iako je korisno da se Java pomoću podrazumevanih vrednosti brine o
neinicijalizovanim promenljivima, dobra programerska praksa je da se ne
23
oslanja na to, već da se eksplicitno inicijalizuje svaka promenljiva koja je
deklarisana.
Pretvaranja između prostih tipova (konverzija)
Ponekad već imamo promenljivu nekog tipa i želimo da je koristimo kao da je nekog drugog
tipa. Tada se vrši pretvaranje (eng. cast) promenljive iz jednog tipa u drugi. Na primer, u jeziku
Java, promenljiva se može pretvoriti iz jednog tipa u drugi na sledeći način:
float fDostignuce = 3.2f;
int iDostignuce = (int)fDostignuce;
U ovom slučaju, broj 3.2 u pokretnom zarezu, koji je smešten u promenljivu fDostignuce biće
pretvoren u ceo broj i smešten u promenljivu iDostignuce. Po pretvaranju u ceo broj, razlomljeni
deo promenljive fDostignuce biva odsečen, pa promenljiva iDostignuce dobija vrednost 3.
Ovo je primer takozvane konverzije sužavanjem. Konverzija sužavanjem može dovesti do
gubljenja informacije, bilo u opsegu, bilo u preciznosti numeričke veličine (to je i bio slučaj u
prethodnom primeru). Zbog tog potencijalnog gubitka podataka, konverziju sužavanjem uvek
treba izvršavati veoma pažljivo i promišljeno.
Druga vrsta pretvaranja se naziva konverzija širenjem. Konverzija širenjem može dovesti do
gubljenja preciznosti samo u bitu najmanje težine date vrednosti, ali neće doći do gubitka
informacije u opsegu vrednosti koja se konvertuje. U opštem slučaju, konverzija širenjem je
mnogo sigurnija. Sledeća tabela prikazuje raspoložive konverzije širenjem između Java prostih
tipova.
Raspoložive konverzije širenjem između Java prostih tipova
Od
Prema
byte
short, int, long, float, double
short
int, long, float, double
char
int, long, float, double
int
long, float, double
long
float, double
float
double
24
Kontrolne strukture
Kontrolne strukture određuju redosled izvršavanja u Java programima, zasnivajući se na
vrednostima promenljivih i logičkim uslovima. Postoje tri osnovne kategorije iskaza kontrole
toka:
•
Iskazi izbora: if, if-else, switch
•
Iteracija (ciklusi, petlje): while, do-while, for
•
Skokovi: break, continue, return, try-catch-finally, assert.
Kontrole toka koristimo kada želimo da promenimo podrazumevani redosled izvršavanja
naredbi.
If naredba
Nardeba if je testiranje jednog logičkog izraza. Ako pri evaluaciji logički izraz dobije vrednost
true, izvršavaju se naredbe koje slede iza if. S druge strane, ako se pri izračunavanju logičkog
izraza dobije vrednost false, naredbe koje slede iza if se ne izvršavaju.
Jednostavan if iskaz ima sledeću sintaksu:
if (<conditional expression>)
<statement action>
public class IfStatementDemo {
public static void main(String[] args) {
int a = 10, b = 20;
if (a > b)
System.out.println(”a > b”);
if (a < b)
System.out.println(”b > a”);
}
}
Izlaz:
b>a
If-else iskaz
If-else iskaz je proširenje if iskaza. Ako uslov dodeljen if iskazu nije tačan, izvršiće se skup
naredbi pridružen else bloku.
25
If-else iskaz ima sledeću sintaksu:
if (<conditional expression>)
<statement action>
else
<statement action>
public class IfElseStatementDemo {
public static void main(String[] args) {
int a = 10, b = 20;
if (a > b) {
System.out.println(”a > b”);
} else {
System.out.println(”b > a”);
}
}
}
Izlaz:
b>a
/* Primer If iskaza */
public class SimpleIfStatementExample {
public static void main(String[] args) {
boolean blnStatus = true;
if(blnStatus)
System.out.println("Status is true");
}
}
/*
Izlaz programa će biti:
Status is true
*/
/* Primer If Else iskaza */
public class SimpleIfElseStatementExample {
26
public static void main(String[] args) {
int i = 0;
if(i == 0)
System.out.println("i je 0");
else
System.out.println("i nije 0");
}
}
/*
Izlaz programa će biti:
i je 0
*/
/* Primer If Else-If iskaza */
public class IfElseIfElseExample {
public static void main(String[] args) {
int i = 10;
if(i > 100)
System.out.println("i je vece od 100");
else if(i > 50)
System.out.println("i je vece od 50");
else
System.out.println("i je manje od 50");
}
}
/*
Izlaz programa će biti:
i je manje od 50 */
/*Primer if…else if…else iskaza*/
import java.util.Date;
Date danas = new Date();
if (danas.getDay() == 0)
System.out.println("Danas je nedelja.");
else if (danas.getDay() == 1)
System.out.println("Danas je ponedeljak.");
else if (danas.getDay() == 2)
27
System.out.println("Danas je utorak.");
else if (danas.getDay() == 3)
System.out.println("Danas je sreda.");
else if (danas.getDay() == 4)
System.out.println("Danas je cetvrtak.");
else if (danas.getDay() == 5)
System.out.println("Danas je petak.");
else
System.out.println("Mora biti da je danas subota.");
Switch iskaz
Kao što se vidi iz prethodnog primera, dugačak niz naredbi if…else if…else može postati težak
za čitanje i razumevanje, naročito sa porastom broja slučajeva. Na sreću, taj problem se može
izbeći korišćenjm Java switch naredbe. Java switch naredba je idealna za proveru jednog izraza
koji pri evaluaciji može da se izračuna u čitav niz vrednosti, i za izvršavanje instrukcija naspram
odgovarajuće case grane, kako je i prikazano u sledećem primeru:
import java.util.Date;
Date danas = new Date();
switch (danas.getDay())
{
case 0: // Nedelja
System.out.println("Danas je nedelja.");
break;
case 1: // Ponedeljak
System.out.println("Danas je ponedeljak.");
break;
case 2: // Utorak
System.out.println("Danas je utorak.");
break;
case 3: // Sreda
System.out.println("Danas je sreda.");
break;
case 4: // Cetvrtak
System.out.println("Danas je cetvrtak.");
break;
case 5: // Petak
System.out.println("Danas je petak.");
System.out.println("Lep provod za vikend!");
break;
default: // Subota
System.out.println("Mora biti da je danas subota.");
}
28
System.out.println("Gotovo!");
Uočava se da svaki od dana ima svoju case granu unutar switch naredbe. Slučaj subote (kada je
danas.getDay() jednako 6) nije dat eksplicitno, već je obrađen pomoću grane default. Svaki
switch blok može da ima opcionalnu default granu u kojoj će biti obrađeni oni slučajevi (tj.
vrednosti izraza - selektora) koji nisu obuhvaćeni eksplicitnim case granama.
Unutar svake case grane, može biti više linija koda (preciznije, više naredbi). Ključna reč break
se koristi u okviru case grane da bi prebacio izvršavanje programa na prvu naredbu koja sledi iza
switch bloka. Naredba break nije potrebna na kraju default grane - kad se pri izvršavanju
programa stigne do te tačke, izvršavanje switch se završava bez obzira da li postoji ili ne postoji
break.
Naravno, postoje i situacije u kojima ne treba da naredba break bude na kraju svake case grane.
Razmotrimo sledeći primer, koji može poslužiti kao aplikacija za organizovanje vremena:
import java.util.Date;
Date danas = new Date();
switch( danas.getDay() )
{
case 0: // Nedelja
case 3: // Sreda
case 6: // Subota
System.out.println("Danas je dan za golf!");
break;
case 2: // Utorak
System.out.println("Tenis u 8:00");
case 1: // Ponedeljak
case 4: // Cetvrtak
case 5: // Petak
System.out.println("Radno vreme: 10:00 - 17:00");
break;
}
System.out.println("Gotovo!");
Uočavamo da je moguće imati više grana koje izvršavaju isti blok koda.
Pored switch naredbi kod kojih selektorski izraz vraća celobrojnu vrednost, mogu se koristiti i
znakovne vrednosti:
switch (znak)
29
{
case 'a': case 'A':
case 'e': case 'E':
case 'i': case 'I':
case 'o': case 'O':
case 'u': case 'U':
System.out.println("Radi se o samoglasniku!");
break;
default:
System.out.println("Radi se o suglasniku!");
}
30
Operatori
Operatori nekog jezika služe za kombinovanje i promenu vrednosti. Java sadrži veoma bogat
skup operatora. Sledi kompletna lista Java operatora:
Kompletna lista Java operatora
<
!
=
>
~
?
:
==
<=
>=
|=
&&
||
++
--
+
-
*
/
&
|
^
%
<<
>>
>>>
+=
-=
*=
/=
&=
|=
^=
%=
<<=
>>=
>>>=
Operatori nad celobrojnim vrednostima
Naveći broj Java operatora deluje nad celobrojnim vrednostima. Tabele koje slede opisuju
binarne operatore (one operatore koji zahtevaju dva operanda) i unarne operatore (zahtevaju
tačno jedan operand) nad celim brojevima. Obe tabela prikazuju i primere korišćenja pobrojanih
operatora.
Binarni operatori nad celobrojnim vrednostima
Operator
Operacija
Primer
=
Dodela
a=b
==
Provera jednakosti
a == b
!=
Provera nejednakosti
a != b
<
Manje od
a<b
<=
Manje ili jednako od
a <= b
>=
Veće ili jednako od
a >= b
>
Veće od
a>b
+
Sabiranje
a+b
-
Oduzimanje
a-b
*
Množenje
a*b
/
Deljenje
a/b
%
Ostatak pri deljenju
a%b
<<
Pomeranje (šiftovanje) ulevo
a << b
31
>>
Pomeranje (šiftovanje) udesno
a >> b
>>>
Pomeranje (šiftovanje) udesno sa nulama
a >>> b
&
Bitovna konjukcija (AND)
a&b
|
Bitovna disjunkcija (OR)
a|b
^
Bitovna ekskluzivna disjunkcija (XOR)
a^b
Unarni operatori nad celobrojnim vrednostima
Operator
Operacija
Primer
-
Unarna negacija
-a
~
Bitovna logička negacija (NOT)
~a
++
Inkrementiranje
a++ ili ++a
--
Dekrementiranje
a-- ili --a
Pored prethodno pobrojanih operatora, Java sadrži i skup operatora koji su bazirani na drugim
operatorima. Ti operatori deluju na levi operand i rezultat operacije smeštaju u taj levi operand.
Na primer, uvećanje promenljive x za 3 može da se uradi na sledeći način:
x += 3;
Ovo odgovara nešto dužem x = x + 3. Svaki od specijalizovanih Java operatora izvršava svoju
normalnu funkciju nad operandima i smešta dobijeni rezultat u levi operand. Java raspolaže
sledećim dodatnim operatorima dodele:
+=
Celobrojni operatori dodele
-=
*=
/=
&=
|=
^=
%=
<<=
>>=
>>>=
Operatori nad vrednostima u pokretnom zarezu
Java operatori nad vrednostima u pokretnom zarezu su podskup operatora koji su dostupni
celobrojnim tipovima. Sledeća tabela opisuje operatore kod kojih su operandi tipa float ili
double, kao i primere njihovog korišćenja.
32
Binarni operatori nad vrednostima u pokretnom zarezu
Operator
Operacija
Primer
=
Dodela
a=b
==
Provera jednakosti
a == b
!=
Provera nejednakosti
a != b
<
Manje od
a<b
<=
Manje ili jednako od
a <= b
>=
Veće ili jednako od
a >= b
>
Veće od
a>b
+
Sabiranje
a+b
-
Oduzimanje
a-b
*
Množenje
a*b
/
Deljenje
a/b
-
Unarna negacija
-a
++
Inkrementiranje
a++ ili ++a
--
Dekrementiranje
a-- ili --a
Operatori nad logičkim vrednostima
Java operatori nad logičkim vrednostima su sumarno prikazani u tabeli koja sledi. Programeri
koji su već radili u C-u ili C++-u su verovatno već familijarni sa ovim operatorima.
Operator
Operatori nad logičkim vrednostima
Operacija
Primer
!
Negacija
!a
&&
Konjukcija
a && b
||
Disjunkcija
a || b
==
Jednakost
a == b
!=
Nejednakost
a != b
?:
Uslovni operator
a ? expr1 : expr2
Uslovni operator je jedini ternarni (sa tri operanda) operator u Javi. On ima sledeću sintaksnu
formu::
logickiIzraz ? izraz1 : izraz2
Efekat izračunavanja, tj. evaluacije uslovnog operatora je sledeći: evaluira se vrednost izraza
logickiIzraz i ako je izračunata vrednost true, tada se izvršava izraz1; ako je izračunata vrednost
33
pri evaluaciji false, izvršava se izraz izraz2 is executed. Na ovaj način, uslovni operator postaje
pogodna skraćenica za sledeći programski segment:
if(logickiIzraz)
izraz1
else
izraz2
/* Aritmetički operatori: + (addition), - (subtraction), * (multiplication) i / (division). */
public class ArithmaticOperatorsExample {
public static void main(String[] args) {
System.out.println("Primer aritmetickih operatora:");
int i = 50 + 20;
int j = i - 10;
int k = j * 2;
double l = k / 6;
System.out.println("i = " + i);
System.out.println("j = " + j);
System.out.println("k = " + k);
System.out.println("l = " + l);
}
}
/*
Izlaz:
Primer aritmetickih operatora:
i = 70
j = 60
k = 120
l = 20.0
*/
/* Aritmetički operatori dodele: +=, -=, *= i /=. */
public class ArithmaticAssignmentOperatorExample {
public static void main(String[] args) {
int i = 5;
int j = 10;
34
i += 5; //isto kao i = i + 5
j -= 2; //isto kao j = j - 2
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}
/*
Izlaz:
i = 10
j=8
*/
/* Operatori inkrementacije i dekrementacije (++) i (--) operator */
public class IncrementDecrementOperatorExample {
public static void main(String[] args) {
int i = 10;
int j = 10;
i++;
j++;
System.out.println("i = " + i);
System.out.println("j = " + j);
int k = i++;
int l = ++j;
System.out.println("k = " + k);
System.out.println("l = " + l);
}
}
/*
35
Izlaz:
i = 11
j = 11
k = 11
l = 12
*/
/* Operator mod */
public class ModulusOperatorExample {
public static void main(String[] args) {
System.out.println("Java Mod Operator");
int i = 50;
double d = 32;
System.out.println("i mod 10 = " + i%10);
System.out.println("d mod 10 = " + d%10);
}
}
/*
Izlaz:
Java Mod Operator
i mod 10 = 0
d mod 10 = 2.0
*/
Iteracija (ciklusi, petlje)
Petlje se koriste u situacijama kada je potrebno da se određeni deo koda izvršava više puta.
Sastavni delovi petlje su uslov petlje i blok petlje - dok je uslov tačan, blok petlje se ponavlja.
Kada zadati uslov postane netačan, ponavljanje se prekida i program nastavlja sa izvršavanjem.
Postoje i petlje kod kojih se blok koda ponavlja sve dok je određeni uslov netačan. Kada postane
tačan, ponavljanje se prekida.
Iteracija je važan koncept u skoro svim programskim jezicima. Ako u nekom programskom
jeziku ne bi bilo mogućnosti da se izvrši iteracija kroz neki skup vrednosti, tada bi bila ozbiljno
ograničena mogućnost da se u tom programskom jeziku rešavaju problemi iz realnog sveta.
U programskom jeziku JAVA postoje sledeće vrste petlji:
•
•
while petlja
do...while petlja
36
•
for petlja
While petlja
While petlja je kontrolna iterativna struktura koja izvrsava deo koda dok je uslov tacan. Uslov
petlje mora biti logickog tipa.
Sintaksa while petlje je sledeca:
while (uslov)
naredba
Kao što se vidi iz sintakse, Java while petlja nema podršku za inicijalizaciju i uvećavanje
promenljivih. Stoga se kod while petlje moraju pažljivo inicijalizovati brojači pre petlje i vršiti
inkrementacija brojača u telu petlje. Na primer, sledeći fragment koda pet puta prikazuje liniju sa
porukom:
int brojac = 0;
while( brojac < 5 )
{
System.out.println("Brojac = " + brojac);
brojac++;
}
Primer2: stampanje brojeva od 1 do 10:
public class WhileLoopDemo {
public static void main(String[] args) {
int count = 1;
System.out.println(”Printing Numbers from 1 to 10″);
while (count <= 10) {
System.out.println(count++);
}
}
}
Izlaz ce biti:
Printing Numbers from 1 to 10
1
2
3
4
5
6
37
7
8
9
10
do-while petlja
Do-while petlja je slična while petlji, sa tom razlikom sto se istinitost uslova proverava na kraju
petlje, a ne na početku, kao sto je slučaj sa while petljom.
Sintaksa za do…while petlju je:
do
{
naredba
} while (uslov);
Ova naredba je, slična while petlji, s time što se telo do…while petlje garantovano izvrši bar
jednom.
S druge strane, moguće je da se telo while petlje nijednom ne izrši (što zavisi od rezultata
izračunavanja uslova). Na primer, uočimo sledeći metod:
public void PrikaziGodine(int godina)
{
while (godina < 2010)
{
System.out.println("Godina " + godina);
godina++;
}
}
Ovom metodu se prosleđuje celobrojna vrednost i on prikazuje sve godine od prosleđene
vrednosti do 2010. Šta će se dogoditi ako prosleđena godina bude 2020? Zbog inicijalnog testa,
godina < 2010, čijom evaluacijom se dobija false, neće se ni ući u while petlju.
public void PrikaziGodine(int godina)
{
do {
System.out.println("Godina " + godina);
godina++;
}
while (godina < 2010)
38
}
For petlja
For petlja je iterativna konstrukcija koja izvršava niz naredbi specifirani broj puta. Brojač petlje
kontroliše petlju, tj. izvršavanje naredbi.
Prva linija for petlje omogućava programeru da postavi startnu vrednost brojača petlje,
specificira uslov koji se proverava radi kontrole ostanka u petlji i da podesi kako će se brojač
petlje menjati posle svakog prolaska kroz telo petlje.
Java sintaksa za for naredbu je:
for (inicijalizacija; uslov; menjanje)
naredbe
Na primer, for petlja može izgledati ovako:
int brojac;
for (brojac=0; brojac<100; brojac++)
System.out.println( "Brojac = " + brojac );
U ovom primeru, inicijalizacioni deo for petlje postavlja brojač na 0. Izraz koji predstavlja uslov
ostajanja u petlji, brojac < 100, ukazuje da će petlja nastaviti da se izvršava sve dok je vrednost
promenljive brojac manja od 100. Na kraju, naredbe u delu za menjanje ukazuju da se vrednost
brojac-a uvećava za jedan. Dokle god je uslov ostajanja u petlji true, izvšava se telo petlje, tj.
naredba koja neposredno sledi iza for naredbe:
System.out.println( "Brojac = " + brojac );
Naravno, često je neophodno da se u telu petlje uradi više od jedne stvari. To se, isto kao kod if
strukture, postiže korišćenjem vitičastih zagrada za označavanje opsega tela for petlje, kao što je
i pokazano u sledećem primeru:
int brojac;
for (brojac =0; brojac<100; brojac++)
{
NekiMetod( brojac );
39
System.out.println( "Brojac = " + brojac );
}
U Java programima se često vidi kako se u okviru for petlje istovremeno i deklariše i inicijalizuje
promenljiva koja se koristi unutar petlje. Na primer, u sledećem kodu, promenljiva brojac je
deklarisana direktno unutar for petlje:
for (int brojac=0; brojac<100; brojac++)
System.out.println( "Brojac = " + brojac );
Na prvi pogled, može izgledati da je mala razlika u tome da li je promenljiva deklarisana pre for
petlje ili unutar nje. Međutim, to nije tako: razlike su značajne. Prvo, deklarisanjem promenljive
unutar petlje, programer jasno stavlja do znanja čemu služi ta promenljiva. Ako se promenljiva
definiše iznad for petlje, kako se može znati da je ta promeljiva namenjena samo za unutrašnjost
petlje? Nadalje, promenljiva deklarisana unutar petlje ima kao opseg definisanosti samo tu petlju
i ona nestaje po izlasku iz petlje. Ovo znači da je programski kod koji sledi nekorektan:
for (int brojac=0; brojac<100; brojac++)
System.out.println( "Brojac = " + brojac );
System.out.println( "Brojac (po izlasku iz petlje) = " + brojac );
Poslednja linija ne može da nađe promeljivu sa imenom brojac zato što je brojac nestao u
trenutku kada je for petlja završila sa radom. Na ovaj način, dakle, nije moguće da programer
napravi grešku i promenjivu koja ima smisla samo unutar petlje počne da koristi za nešto drugo.
Neki delovi tj. sekcije for naredbe mogu i da budu prazni. U sledećem primeru izostavljena je
sekcija za menjanje:
for (brojac =0; brojac<100; )
{
brojac += 2;
System.out.println( "Brojac = " + brojac );
}
Moguće je da u sekcijama for naredbe bude više naredbi. Na primer, razmotrimo sledeći kod:
for (int gore=0, dole = 20; gore < dole; gore++, dole -= 2 )
40
{
System.out.println("Gore = " + gore + "\tDole = " + dole);
}
Petlja počinje sa vrednošću promenljive gore od 0 i uvećava je za 1. Ona takođe počinje sa
vrednošću promenljive dole od 20 i smanjuje je za 2 posle svakog prolaska kroz telo petlje.
Petlja se vrti sve dok vrednost promenljive gore ne postane veća ili jednaka od vrednosti
promeljive dole.
Uslov u Java for petlji može biti ma koji logički izraz. Stoga, to ne mora da bude prosto
poređenje, (npr. x < 10) kakvo je bilo u prethodnim primerima. Uslov može biti poziv metoda,
poziv metoda u kombinaciji sa poređenjem vrednosti, ili bilo šta što prilikom evaluacije daje
logičku vrednost. Na primer, želimo da napišemo metod koji će prikazati poruku sa godinama
(posle 1950) kada Barselona nije pobedila u fudbalskom šampionatu. To se može uraditi na
sledeći način:
public boolean BarselonaNijeSampion(int godina)
{
boolean rezultat;
switch(godina)
{
case 1947:
case 1948:
rezultat = true;
break;
case 1952:
case 1953:
case 1958:
case 1969:
case 1972:
case 1975:
case 1978:
case 1985:
rezultat = true;
break;
default:
rezultat = false;
}
return rezultat;
}
public void BarselonaNijeSampionOd1950()
41
{
for (int god=1950; BarselonaNijeSampion(god)==false; god++)
{
System.out.println("Barselona nije bila sampion drzave " + god);
}
}
Metod BarselonaNijeSampion() ima jedan celobrojni argument koji predstavlja godinu, a vraća
logičku vrednost koja ukazuje da li je te godine fudbalski klub Barselona uspeo da postane prvak
države. Metod je realizovan korišćenjem naredbe switch koja je opisana u prethodnom poglavlju.
Metod BarselonaNijeSampionOd1950 koristi for petlju da bi pronašao godine počev od 1950-te
u kojoj Barselona nije bila šampion. Petlja koristi promenljivu god čija se vrednost postavlja na
1950 i inkrementira god za jedan posle svakog prolaska kroz telo petlje. Uslov za izlazak dopušta
izvršavanje petlje dokle god metod BarselonaNijeSampion vraća vrednost false. Ovo je koristan
primer, jer pokazuje kako metod može biti pozvan iz uslova for petlje.
42
Kontrolne naredbe skoka – break i continue
Kontrolne naredbe skoka se koriste za izmenu redosleda izvršavanja naredbi unutar petlji
(prekid, prelazak na sledeću iteraciju, završavanje programa itd).
Nije uvek lako pisati sve for, while i do…while petlje tako da je kod lako čitljiv i da istovremeno
radi kako treba – da izlasci iz petlji budu na pravim mestima. Zato programski jezik Java sadrži
naredbe break i continue koje olakšavaju izlazak iz petlji i kontrolisanje ostalih delova programa.
Naredba break
Već ranije smo koristili naredbu break statement kako bi izašli iz switch naredbe. Na sličan način
se komanda break može koristiti za izlazak iz petlje (kao na sledećoj slici).
Kao što se vidi, po nailasku na break naredbu izvršavanje se nastavlja od naredbe statement4.
Razmotrimo sledeći kod kao primer:
int godina = 1986;
while( BarselonaNijeSampion(godina) == false )
{
System.out.println("Barselona je sampion prvenstva " + godina);
if( godina >= 3000 )
{
System.out.println("Predajem se. Barselona je najbolja!");
break;
}
}
System.out.println("Izasli smo iz petlje u godini " + godina);
U ovom primeru se koristi while petlja koja se izvršava sve dok ne nađe godinu u kojoj
Barselona nije bila pobednik prvenstva. Pošto je Barselona poslednji put izgubila 1985, a brojač
petlje počinje od 1986, petlja će se izvršavati jako dugo. Za svaku godinu kad je Barselona bila
43
šampion, u telu petlje će se prikazati odgovarajuća poruka. Stoga je u ovom primeru, ako je
godina 3000-ta ili kasnija, ispisana odgovarajuća poruka o predaji i postavljena break naredba.
Izvršenje break naredbe će dovesti do prelaska izvršenja na prvu naredbu posle while petlje. U
tom slučaju, izvršiće se sledeća naredba:
System.out.println("Izasli smo iz petlje u godini " + godina);
Postoje break naredbe sa i bez labela. Naredbe bez labela se koriste kada hoćemo da izađemo
iz jednostruke petlje ili switch-iskaza, a labele kada hoćemo da izađemo iz ugnježdenih.
Naredba continue
Isto kao što break naredba može biti korišćena za prelazak izvršavanja na prvu naredbu iza kraja
petlje, tako naredba continue može da se koristi za prebacivanja izvršenja na početak petlje (što
je i prikazano na sledećem dijagramu):
Pretpostavimo da treba prebrojati i prikazati poruke za godine kada je Barselona bila šampion (u
periodu 1946 - 2000), kao i ukupan broj trijumfalnih godina za Barselonu. Ovo može biti
urađeno na sledeći način:
int brojTrijumfa = 0;
for( int godina=1946; godina <= 2000; godina++ )
{
if( BarselonaNijeSampion(godina) )
continue;
System.out.println("Barselona je sampion prvenstva " + godina);
brojTrijumfa++;
}
System.out.println("Barselona je ukupno trijumfovala: " + brojTrijumfa );
44
U gornjem slučaju, koristi se for petlja za iteraciju kroz godine od 1900 do 2000. Prva naredba u
telu petlje provera da li je Barselona te godine bila šampion. Ako nije bila šampion, izvršava se
continue naredba i programska kontrola se vraća na for petlju. To znači da se promenljiva godina
inkrementira i da se ponovo evaluira vrednost izraza godina <= 2000. Ako je vrednost
promenljive godina manja ili jednaka od 2000, nastavlja se izvršavanje u petlji. Ako te godine
Barselona nije bila šampion, štampa se odgovarajuća poruka, inkrementira ukupan broj trijumfa i
programska kontrola se takođe vraća na for petlju.
Korišćenje labela
Java ne sadrži “goto” naredbu. Međutim, činjenica da je goto rezervisana reč ukazuje da ona
može biti dodata u budućim verzijama. Umesto korišćenja goto naredbe, Java dopušta
kombinaciju break i continue naredbi sa labelom. Ovo ima efekat sličan goto naredbi u tome što
dopušta premeštanje programske kontrole. Razmotrimo sledeći primer:
public void paint(Graphics g)
{
int linija=1;
spoljnaPetlja:
for( int spoljni=0; spoljni < 3; spoljni++ )
{
g.drawString("spoljni = " + spoljni, 5, linija * 20);
linija++;
for( int unutrasnji=0; unutrasnji < 5; unutrasnji++ )
{
double slucajni = Math.random();
g.drawString(Double.toString(slucajni), 15, linija * 20);
linija++;
if (slucajni < .10)
{
g.drawString("Povratak u spoljnju ", 25, linija * 20);
liija++;
break spoljnaPetlja;
}
if ( slucajni < .60)
{
g.drawString("Nastavak u spoljnoj", 25, linija * 20);
linija++;
continue spoljnaPetlja;
}
}
}
45
g.drawString("Gotovo", 50, linija * 20);
}
Ovaj primer uključuje dve petlje, jednu u drugoj. Spoljnja petlja je dobila labelu:
spoljnjaPetlja:
Tom naredbom je postavljena labela-držač i ime za spoljašnju petlju. Normalna break naredba bi
prekinula samo izvršavanje unutrašnje petlje. Međutim, ovde se radi o break naredbi sa labelom,
pa se izlazi iz petlje koja ima naziv te labele – u konkretnom slučaju prikaže se tekst «Gotovo».
Potpuno analogno se ponaša i labelirana continue naredba – prenosi izvršavanje na početak
labelirane petlje.
46
JAVA KLASE
Klasa definiše skup objekata koji se ponašaju na isti način. Ona definiše podatke i ponašanje
objekata koji se iz nje prave, tj. instanciraju. Definiciju klase koristimo da napravimo objekat tog
tipa klase, odnosno da napravimo objekat koji u sebi sadrži sve komponente koje pripadaju klasi.
Klasa sadrži polja i metode.
•
•
Polja su promenljive koje skladište podatke koji tipično razlikuju jedan objekat klase od
drugog. Nazivaju se još i članovi – podaci.
Metode definišu operacije koje možemo izvoditi za klasu – oni dakle određuju šta se
može uraditi objektu ili sa objektom klase. Metodi tipično operišu nad poljima –
promenljivima klase.
Postoje 2 vrste promenljivih u definiciji klase .
Jedna vrsta promenljivih je združena sa svakim objektom jedinstveno – svaka instance klase će
imati svoje kopije od svake od ovih promenljivih sa sopstvenim, dodeljenim vrednostima. One
razlikuju jedan objekat od drugog dajući objektu individualnost. Te promenljive se nazivaju
promenljive instance.
Druga vrsta promenljivih klase je združena sa klasom i nju dele svi objekti klase. Postoji samo
po jedna kopija od svake promenljive, bez obzira koliko je objekata klase napravljeno. Te
promenljive se nazivaju promenljive klase. One se takođe nazivaju i statična polja, jer se za
njihovu deklaraciju koristi reč static.
Java klasa je pojam iz vremena kompilacije, koji predstavlja objekat u vremenu izvršavanja.
Drugim rečima, klasa je definicija šablona za objekat koji će da postoji unutar programa. Na
primer, ako imamo klasu Automobil, možemo imati konkretnu instancu (član) te klase koji je
Folksfagen Buba iz 1966. Instance (Folksfagen Buba 1966) klase (Automobil) se nazivaju
objekti. Da bi se definisala klasa u Javi, treba uraditi nešto slično sledećem:
class Automobil
{
// promenljive - clanovi
// metodi - clanovi
}
Deklaracije polja
Automobil je u ovom trenutku prazna klasa. Da bi ova klasa postala korisna, potrebno je da se
dodaju neka polja u klasu. Polje može biti promenljiva-član ili promenljiva-metod. Za
47
deklaraciju promenljive-člana, potrebno je da se identifikuje tip promenljive i naziv promenljive
unutar definicije klase, kao što je i prikazano:
class Automobil
{
// promenljive - clanovi
String proizvodjac;
String model;
int godinaProizvodnje;
int brojPutnika;
}
U ovom primeru, klasa Automobil je dograđena tako da uključi string promenljive za
proizvođača i model i celobrojne promeljive koje predstavljaju godinu proizvodnje i broj putnika
koji se može naći u vozilu.
Pristup polju
Jedna od osnovnih prednosti u objektno-orjentisanom programiranju je enkapsulacija
(učaurenje). Enkapsulacija je sposobnost klase da sakrije detalje implementacije od ostalih klasa,
izlažući samo javni interfejs ostalim klasama. Podrška za enkapsulaciju u Javi se oslanja na tri
ključne reči: public, private, i protected. Kada se definiše klasa, ovi modifikatori za pristup polju
se koriste za kontrolu ko može pristupiti konkretnom polju klase. Ako se polje deklariše kao
public (srp. javno), time se određuje da se tom polju može pristupiti iz ma koje druge klase.
Nastavljajući primer sa klasom Automobil, za deklaraciju svih polja klase kao javnih polja, treba
uraditi sledeće:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika;
}
Naravno, deklarisanjem svega kao javnog ne postiže se cilj enkapsulacije, jer to dopušta da druge
klase direktno prispupaju promenljivima iz klase Automobil. Razmotrimo, na primer, šta bi se
dogodilo ako se kreira instanca klase za Ford Mustang iz juna 1964. S obzirom da
godinaProizvodnje može sadržati samo celobrojne promenljive, pokušaj da se vrednost postavi
48
na 1964.5 bi proizveo izuzetak. Dakle, ako bi bilo omogućeno da se godinaProizvodnje postavlja
iz drugih klasa, kod bi neizostavno «pukao».
Ključna reč private (srp. privatan) se koristi za restrikciju pristupa polju. Klasa ne može pristupiti
privatnom polju neke druge klase. Pretpostavimo da klasa Automobil treba da se koristi u nekoj
aplikaciji za prodaju automobila. U tom slučaju, potrebno je da se klasa Automobil definiše na
sledeći način, kako bi cena bila sakrivena od potencijalnih kupaca:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika;
private float cena;
}
Na kraju, ključna reč protected (srp. zaštićen) se koristi da bi ukazala da se polju može pristupiti
iz tekuće klase i iz svih klasa koje su izvedene iz tekuće klase, ali ne iz drugih klasa.
Postavljanje inicijalnih vrednosti
Jedna izuzetno lepa osobina Java klasa je mogućnost da se specificiraju inicijalne vrednosti za
promenljive-članove u samoj deklaraciji promenljive-člana. Na primer, s obzirom da je najveći
broj automobila registrovan za četiri putnika, ima smisla da se podrazumevana vrednost za
brojPutnika postavi na 4, kako je i prikazano u sledećem kodu:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
}
49
Statički članovi
Pored private, protected, i public članova, Java klasa može da ima statičke članove. Statički član
pripada samoj klasi (ponegde se zbog toga zove i klasni član), a ne instanci neke klase. Bez
obzira koliko instanci klase biva kreirano tokom rada programa, postojaće tačno jedna instanca
svakog statičkog člana. Deklarisanje statičkog člana se obavlja dodavanjem ključne reči static
(srp. statičan) na druge modifikatore pristupa polju, kako je i prikazano u sledećem primeru:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
public static int brojGuma = 4;
}
U ovom slučaju, promenljiva brojGuma je uključena i postavljena na vrednost 4. S obzirom da
svaki automobil ima četiri gume, brojGuma se deklariše kao static. Nadalje, budući da brojGuma
treba da bude pristupačan i drugim klasama, on će biti deklarisan kao public.
Takođe je moguće da se metodi-članovi deklarišu kao statički.
Metodi-članovi
Pored članova-promenljivih, najveći broj klasa takođe ima i članove-metode. Budući da su
metode-članovi, kao i promenljive-članovi, polja, pristup im se kontroliše sa modifikatorima
public, protected i private. Metod-član se deklariše prema sledećoj sintaksi, pri čemu uglaste
zagrade ukazuju na opcionalnost elementa:
[modifikatoriMetoda] tipRezultata imeMetoda [throws listaIzuzetaka]
{
// telo metoda
}
Konstrukt modifikatoriMetoda su već poznate ključne reči public, protected i private sa istim
značenjem koje su i ranije imali. Modifikatori metoda su opisani u sledećoj tabeli.
50
Modifikatori metoda
Svrha
Modifikator
public
Pristupačno i van klase u kojoj je deklarisano.
protected
Pristupačno unutar klase u kojoj je deklarisano i iz
podklasa od te klase.
private
Pristupačno isključivo
deklarisano.
static
Metod pripada klasi, a ne konkretnoj instance te klase.
abstract
Nije implementirana u toj klasi.
fiinal
Ne može biti predefinisana u podklasama.
native
Implementacija zavisna od platforme, realizovana u
drugom jeziku, obično C-u ili asembleru.
synchronized
Koristi se da indicira kritičan metod, koji će zaključati
objekat kako bi sprečilo izvršavanje ostalih metoda dok
se sinhronizovani metod izvršava.
unutar
klase
u
kojoj
je
tipRezultata u deklaraciji metoda može biti jedan od primitivnih tipova (na primer, int, float,
char), neka druga klasa ili void. Ako je tip rezultata void, to pokazuje da se nijedan rezultat na
vraća pozivaocu metoda. Posle imena metoda, definiše se (po potrebi) lista izuzetaka koje metod
može da podigne. Ako nema izuzetaka koje podiže ovaj metod, onda je lista izuzetaka prazna.
Kao ilustaraciju gornjeg stava, dodajmo metod na klasu Automobil:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
public float SracunajProdajnuCenu()
{
return cena * 1.5;
}
public static int brojGuma = 4;
}
51
U ovom slučaju, klasa Automobil sadrži i javni metod-član, nazvan SracunajProdajnuCenu. Ovaj
metod vraća float i telo metoda izračunava povratnu vrednost.
Preopterećeni metodi
Sposobnost preopterećivanja (eng. overload) methoda je jedna od najvećih prednosti u radu sa
objektno – orjentisanim jezicima, i u tom pogledu Java zasigurno nije razočarenje.
Preopterećenje metoda znači da se koristi isto ime metoda za više od jednog metoda. Na primer,
klasa Automobil može sadržavati dva metoda SracunajProdajnuCenu, kao u sledećem primeru:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
public float SracunajProdajnuCenu()
{
return cena * 1.5;
}
public float SracunajProdajnuCenu( float margina )
{
return cena * (1 + margina);
}
public static int brojGuma = 4;
}
Tokom izvršavanja programa, Java može razlikovati ova dva metoda na osnovu broja i tipova
parametara koji su prosleđeni. Stoga se metod može preopterećivati koliko god treba puta, sve
dok su liste parametata jedinstvene za svaku verziju. Drugim rečima, sledeći kod je nekorektan:
class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
52
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
public float SracunajProdajnuCenu()
{
return cena * 1.5;
}
public float SracunajProdajnuCenu( float margina )
{
return cena * (1 + margina);
}
public float SracunajProdajnuCenu( float cinilac )
{
return cena * cinilac;
}
public static int brojGuma = 4;
}
U ovoj situaciji, poslednje dve deklaracije su u konfliktu, zato što svaka od njih prosleđuje
double. Različita imena parametara nisu dovoljna za razlikovanje između dve verzije iste
preopterećene funkcije. Da bi se preopterećene funkcije razlikovale, one se moraju razlikovati u
bar jednom tipu parametara.
Konstruktori
Specijalni tip metoda-člana je poznat kao konstruktor. Konstruktor se koristi prilikom kreiranja
nove instance klase. Konstruktor se prepoznaje po tome što taj metod ima isto ime kao klasa.
Kao i ma koji drugi metod, konstruktor može biti preopterećen onoliko puta koliko god različitih
tipova parametara se javlja u okviru metoda. Obično konstruktor postavlja članove-promenljive
instance na vrednosti koje odgovaraju toj instanci. Konstruktor nema povratni tip. Kao primer,
razmotrimo sledeću varijaciju klase Automobil:
public class Automobil
{
// promenljive - clanovi
public String proizvodjac;
53
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
public float SracunajProdajnuCenu()
{
return cena * 1.5;
}
public float SracunajProdajnuCenu( float margina )
{
return cena * (1 + margina);
}
// javni konstruktor
public Automobil(String pro, String ime, int god, int put,
float cen)
{
proizvodjac = pro;
model = ime;
godinaProizvodnje = god;
brojPutnika = put;
cena = cen;
}
// metod koji vraća string sa osnovnim podacima
public String OsnovniPodaci()
{
return new String(godinaProizvodnje + " " + proizvodjac + " "
+ model);
}
}
Konstruktor, Automobil, je dodat u ovu verziju klase Automobil. Konstruktoru se prosleđuje pet
parametara koji će se koristiti kao inicijalne vrednosti za promenljive-članove
proizvodjac, model, godinaProizvodnje, brojPutnika, cena. Kod za konstruktor jednostavno
postavlja vrednosti za tih pet instancnih promenljivih. Klasa Automobil takođe sadrži i javni
metod-član, OsnovniPodaci, koji kreira string sa osnovnim podacima o automobilu. Korišćenjem
konstruktora i novog metoda OsnovniPodaci, sada se iz druge klase mogu prikazati osnovni
podaci o automobilu. Na primer, sledeći kod će na standardni izlaz prikazati string "1967
Folksvagen Buba":
Automobil mojAuto = new Automobil("Folksvagen ", " Buba", 1967, 4,
54
3000);
String s = mojAuto. OsnovniPodaci();
System.out.println(s);
Nova instanca klase Automobil je kreirana sledećim kodom:
Automobil mojAuto = new Automobil("Folksvagen ", " Buba", 1967, 4,
3000);
Upotreba ključne reči new instruiše Javu da kreira novi objekt tipa Automobil alociranjem
memorije i pozivom konstruktora Automobil, čiji potpis odgovara listi parametara. U
konkretnom slučaju, Automobil ima samo jedan konstruktor, pa se taj konstruktor poziva i
postavlja instncne promenljive na vrednosti parametara. Jednom kad promenljiva mojAuto izađe
iz opsega na kraju funkcije u kojoj je deklarisana, automatsko upravljanje memorijom kod Jave
će detektovati da memorija alocirana operatorom new više nije referencirana i ona će biti
oslobođena.
Napomena
Ako klasa ne sadrži konstruktor, Java će obezbediti podrazumevani
konstruktor koji ne sadrži parametre. Ovaj podrazumevani konstruktor će
dopustiti kreiranje novih instanci date klase i postaviti sve promenljivečlanove novokreirane instance na sistemske podrazumevane vrednosti. Ipak,
opasno je i ne previše mudro da se osloni na postojanje podrazumevanog
Java konstruktora. U opštem slučaju, treba obezbediti bar jedan konstruktor
za svaku novodefinisanu klasu.
Promenljiva this
Sve Java klase sadrže skrivenu promenljivu-član nazvanu this. Promenljiva-član this može da
bude korišćena radi referisanja na sam objekat. Jedan odličan način korišćenja this-a je u
konstruktorima. Uobičajeno je da se u konstruktoru skup promenljivih-članova postavi na
vrednosti koje su kao parametri prosleđeni konstruktoru. U takvim slučajevima, bilo bi dobro da
se u kodu nađe sledeća naredba:
55
godina = godina;
Pri tome, promenljiva na levoj strani treba da bude promenljiva-član, a promenljiva na desnoj
strani parametar koji je prosleđen konstruktoru. Na nesreću, u takvim slučajevima nijedan
kompajler ne može da shvati šta je programer nameravao. Ovakve probleme programeri često
prevazilaze na sledeći način:
public class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
private float cena;
// javni konstruktor
public Automobil(String fabrika, String ime, int god, int nosivost,
float vrednost)
{
proizvodjac = fabrika;
model = ime;
godinaProizvodnje = god;
brojPutnika = nosivost;
cena = vrednost;
}
}
Programer je prinuđen da izmisli dva imena za svaki pojam, pri čemu se ime koje najbolje
opisuje pojam dodeljuje promenljivoj-članu u deklaraciji klase, a nešto slabije ime se daje
parametru u konstruktoru. Na taj način, naredbe dodele su čitljive od strane Jave, ali su pomalo
zbunjujuće za ljude. Ključna reč this obezbeđuje veoma efikasno rešenje za prethodni problem:
public class Automobil
{
// promenljive - clanovi
public String proizvodjac;
public String model;
public int godinaProizvodnje;
public int brojPutnika = 4;
56
private float cena;
// javni konstruktor
public Automobil(String proizvodjac, String model,
int godinaProizvodnje, int brojPutnika, float cena)
{
this.proizvodjac = proizvodjac;
this.model = model;
this.godinaProizvodnje = godinaProizvodnje;
this.brojPutnika = brojPutnika;
this.cena = cena;
}
}
U ovom slučaju, nazivi kao što su this.godinaProizvodnje označavaju promenljive-članove, dok
nekvalifikovani nazivi kao što je godinaProizvodnje označavaju parametre konstruktora.
Naravno, prethodni kod je samo jedan primer kako se može koristiti ključna reč this. Ova ključna
reč se često koristi kao parametar u drugim funkcijama i na mnogobrojne druge načine.
Rekurzija
Rekurzija je postupak definisanja nečega na osnovu istog tog nečega. To je pojava kada metoda
poziva samu sebe, a metoda koja poziva samu sebe naziva se rekurzivna.
Primer:
class Faktorijel
{
int fakt(int n)
{
int rezultat;
if(n==1) rezultat = 1;
rezultat = fakt(n-1)*n;
return rezultat;
}
}
class Rekurzija
{
public static void main(String args[])
{
57
Faktorijel f = new Faktorijel();
System.out.println(„Faktorijel broja 3 je “ + f.fakt(3));
}
Kada metoda pozove samu sebe, za nove lokalne promenljive i parametre rezerviše se prostor na
steku, a metoda se izvršava od početka sa ovim novim promenljivama. Kada svaki rekurzivni
poziv vrati vrednost, prethodne lokalne promenljive i parametri se ukljanjaju sa steka, a
izvršavanje se zavrsava tamo gde je zaustavljenmo unutar metode.
Rekurzivna rešenja se cesto izvršavaju sporije od svojih iterativnih ekvivalenata, zbog brojnih
poziva finkcijama, pa moze doći do prekoračenja steka.
Glavna prednost se ogleda u tome što se pomoću njih mogu napraviti čistije i jednostavnije
verzije nekoliko algoritama nego pomoću korišćenja iterativnih struktura.
Pri pisanju rekurzivne metode obavezno je postaviti uslov završavanja (if naredbu), inače se
pozvana metoda nikada neće završiti. Ovo je vrlo česta GREŠKA!
Nasleđivanje klasa
Nasleđivanje je jedan od kamena temeljaca OOP zato što omogućava pravljenje hijerarhijske
klasifikacije. Pomoću nasledjivanja možemo napraviti opštu klasu koja definiše zajedničke
karakteristike za skup srodnih pojava. Ovu klasu onda mogu da naslede druge, specifičnije klase,
pri čemu svaka dodaje ono što je za nju jedinstveno.
Nasleđena klasa se zove natklasa (superclass).
Klasa koja nasleđuje zove se potklasa (subclass).
Opšti oblik deklaracije klase koja nasleđuje natklasu je:
class imePotklase extends imeNatklase
{
// telo klase
}
Primer nasleđivanja:
//natklasa
class A{
int i, j;
void prikaziij()
{
System.out.println(“i i j je: ” + i + “ ” +j);
}
}
58
//potklasa
class B extends A{
int k;
void zbir()
{
System.out.println(“i+j+k = ” + (i+j+k));
}
}
Kontrola pristupa
Mada potklasa sadrži sve članove svoje natklase, ona ne može da pristupi onim članovima svoje
klase koji su označeni kao privatni (specifikatorom pristupa private).
Promenljiva natklase može da referencira objekat potklase.
To znači da se referentnoj promenljivoj natklase može dodeliti referenca na bilo koju potklasu
izvedenu iz te natklase.
Rezervisana reč super
Kad god potklasa treba da se obrati svojoj neposrednoj natklasi, ona to može da učini pomoću
rezervisane reči super.
Postoje 2 oblika upotrebe reči super:
• za pozivanje konstruktora natklase
• za pristupanje članu natklase koji je bio sakriven članom potklase
U hijerarhiji klasa konstruktori se pozivaju po redosledu izvođenja, od natklase ka potklasi.
Redefinisanje metoda
Kada metoda potklase ima isto ime i tip kao metoda natklase, tada metoda potklase ima prednost
nad metodom natklase – ona je redefiniše (engl. override). Kada se unutar potklase pozove tako
redefinisana metoda, uvek će se izvršiti njena verzija koja je definisana u potklasi. Verzija
metode iz natklase biće sakrivena.
Redefinisanje metoda predstavlja jedan od Javinih najmoćnijih koncepata: dinamičkog
razrešavanja metoda. To je mehanizam pomoću koga se poziv upućen redefinisanoj metodi
razrešuje u trenutku izvršavanja, umesto tokom prevođenja. Na taj način Java realizuje
polimorfizam u trenutku izvršavanja programa.
Obratimo pažnju: referentna promenljiva natklase može da ukaže na objekat potklase. Kada se
redefinisana metoda pozove referenciranjem iz natklase, Java utvrđuje koju će verziju metode da
izvrši na osnovu tipa ukazanog objekta u trenutku upućivanja poziva. Dakle, ovo utvrđivanje se
odvija u trenutku izvršavanja programa. Kada se referenciraju različiti objekti, biće pozivane
59
različite verzije redefinisane metode. Ovo znači da TIP REFERENCIRANOG OBJEKTA
određuje koja će verzija metode biti pozvana, a ne tip referentne promenljive.
Ako natklasa sadrži metodu koja je redefinisana u potklasama, tada će, prilikom referenciranja
različitih objekata pomoću referentne promenljive natklase biti pozivane različite verzije metode.
class A
{
void pozoviMe()
{
System.out.println("Pozovi me unutar A.");
}
}
class B extends A
{
void pozoviMe()
{
System.out.println("Pozovi me unutar B.");
}
}
class C extends A
{
void pozoviMe()
{
System.out.println("Pozovi me unutar C.");
}
}
public class Razresavanje {
public static void main(String args[])
{
A a = new A(); // objekat tipa A
B b = new B();
C c = new C();
A r; // referenca na objekat klase A
r = a;
60
r.pozoviMe();
r = b;
r.pozoviMe();
r = c;
r.pozoviMe();
}
}
Apstraktne klase
Apstraktne klase se koriste da deklarišu zajedničke karakteristike potklasa. Apstraktna klasa ne
može biti instancirana, ona jedino može biti korišćena kao natklasa za druge klase koje je
nasleđuju. Ona, dakle ne može imati objekte – nju ne možemo direktno instancirati operatorom
new. Apstraktne klase se deklarišu pomoću ključne reči abrstract.
Deklaracija:
abstract class ImeKlase
{
//telo klase
}
Apstraktne klase se koriste da bi obezbedile šablon ili dizajn za konkretne potklase koje su niže u
hijerarhiji nasleđivanja.
Kao i svaka druga klasa, apstraktna klasa može da sadrži polja koja opisuju karakteristike i
metode koje opisuju ponašanje, odnosno akcije koje klasa može da izvede. Apstraktna klasa
može da ima metode koje nemaju implementaciju, dakle imaju samo deklaraciju. Ove metode se
zovu apstraktne metode.
Deklaracija:
abstract tip ImeMetode(ListaParametara);
!! NEMA TELA METODE !!
61
Ako neka klasa ima barem jednu apstraktnu metodu - bilo deklarisanu, bilo nasleđenu, cela ta
klasa mora biti deklarisana kao apstraktna. Apstraktne metode se koriste radi obezbeđivanja
šablona za klase koje nasleđuju apstraktne.
Sve klase koje naslede apstraktnu, moraju da definišu sve nasleđene metode koje su apstraktne.
Naravno, svaka od tih definicija može biti predefinisna u nekoj sledećoj potklasi.
Primer:
abstract class A
{
abstract void pozoviMe();
void pozoviIMene()
{
System.out.println("Ovo je jedna konkretna metoda u apstraktnoj klasi A.");
}
}
class B extends A
{
void pozoviMe()
{
System.out.println("Definicija metode pozoviMe() u potklasi B");
}
}
public class Apstrakcija {
public static void main(String args[])
{
B b = new B();
b.pozoviMe();
b.pozoviIMene();
}
}
Apstraktne klase se ne mogu koristiti za pravljenje instanci objekta, ali njima se mogu
referencirati objekti. Redefinisane metode se razrešavaju u trenutku izvršavanja programa,
referenciranjem natklase.
Rezervisana reč final
Rezervisana reč final ima tri namene:
62
1. Za pravljenje konstanti
2. Za sprečavanje redefinisanja
3. Za sprečavanje nasledjivanja
Ako želimo da onemogućimo redefinisanje određene metode, na početak njene deklaracije
stavimo modifikator final. Metode označene sa final ne mogu se redefinisati.
Primer3:
public class A
{
final void radi()
{
System.out.println("Ova metoda se ne moze redefinisati.");
}
}
class B extends A
{
void radi() //GRESKA
{
System.out.println("Nepropisno!");
}
}
Ponekad će biti potrebno da sprečimo nasleđivanje od određene klase. Ako to želimo, dovoljno
je da ispred deklaracije klase umetnemo modifikator final. Kada klasu deklarišemo kao final, i
sve njene metode postaju final, odnosno ne mogu se redefinisati. Očigledno, klasa ne može
istovremeno da bude označena i sa abstract i sa final, pošto je apstraktna klasa nepotpuna, pa se
za potpunu definiciju mora oslanjati na svoje potklase.
Primer4:
public final class A
{
// telo klase
}
class B extends A // GRESKA!
{
//…}
63
Klasa Object
U Javi postoji posebna klasa, klasa Object. Sve ostale klase su potklase klase Object, odnosno,
sve klase nasleđuju ovu klasu. Ovo znači da referentna promenljiva tipa Object može da
referencira objekat u bilo kojoj drugoj klasi. Osim toga, pošto su nizovi napravljeni kao klase,
promenljiva tipa Object može da referencira i niz.
Klasa Object definiše sledeće metode – koje su na raspolaganju u svakom objektu:
Object clone()
Pravi nov objekat koji je isti kao objekat
koji se klonira.
boolean equals(Object objekat)
Utvrđuje da li je jedan objekat jednak
drugom.
void finalize()
Poziva se pre čišćenja nekog nekorišćenog
objekta.
Class getClass()
Pronalazi klasu objekta u trenutku
izvršavanja.
int hashCode()
Vraća ključ za heširanje pridružen objektu
koji se poziva.
void notify()
Nastavlja izvršavanje programske niti koja
čeka pozivaoca.
void notifyAll()
Nastavlja izvršavanje svih programskih niti
koje čekaju pozivaoca.
String toString()
Vraća znakovni niz koji opisuje objekat.
void wait(long milisekinde)
Čeka izvršavanje druge programske niti.
void wait(long milisekinde, int
nanosekunde)
Metode getClass(), notify(), notifyAll() i wait() deklarisane su kao final. Sve ostale možemo da
predefinišemo.
Metoda equals() poredi sadržaj dva objekta i vraća true ako su objekti ekvivalentni. Naravno,
precizna definicija poređenja menja se u zavisnosti od tipa objekata koji se porede.
64
Metoda toString() vraća znakovni niz koji sadrži opis objekata uz koji je pozvana. Ona se
automatski poziva čim se neki objekat ispisuje metodom println().
Paketi
Kada klasi dajemo ime, moramo voditi računa da to ime bude jedinstveno i da se ne sukobljava
sa imenima klasa koje je neko drugi već napisao. Java ima mehanizam za deljenje imenskog
prostora klasa u više segmenata kojima se može lakše upravljati. Taj mehanizam je paket. Paket
je istovremeno mehanizam za imenovanje i za upravljanje vidljivošću. Unutar paketa možemo
definisati klase koje nisu dostupne izvan paketa il ičlanove klase koji su dostupni samo klasama
u okviru istog paketa.
Paketi se prave tako što stavimo komandu package kao prvu naredu Javine izvorne datoteke.
Ako izostavimo ovo, sve klase će biti smeštene u podrazumevani paket koji nema ime.
Naredba ima oblik:
package imePaketa;
Za čuvanje paketa Java koristi sistem direktorijuma. Npr. fajlovi tipa .class za bilo koju klasu
koju deklarišemo unutar paketa MojPaket moraju da budu u direktorijumu MojPaket. Ime
direktorijuma mora tačno da odgovara imenu paketa.
Paketi mogu da obrazuju hijerarhiju. Opšti oblik hijerarhije paketa izgleda ovako:
package paket1.paket2.paket3;
npr: java.awt.image;
Postoje 4 kategorije vidljivosti za članove klase:
1.
2.
3.
4.
potklase u istom paketu
klase iz istog paketa koje nisu potklase
potklase u drugim paketima
klase iz drugih paketa koje nisu potklase
65
private
bez
specifikatora
protected
public
ista klasa
da
da
da
da
potklasa istog
paketa
ne
da
da
da
klase istog
paketa koje
nisu potklase
ne
da
da
da
potklasa iz
drugog paketa
ne
ne
da
da
klase iz drugih
paketa koje
nisu potklase
ne
ne
ne
da
Svemu što je označeno kao public može se pristupiti bilo otkuda. Ono što je označeno kao
private nevidljivo je izvan svoje klase. Sa protected označavamo one članove klase za koji
želimo da bude vidljiv izvan svog paketa, ali samo direktnim potklasama klase u kojoj se nalazi.
Uvoženje paketa
Naredbom import određene klase ili čitav paket činimo vidljivim u okviru nekog drugog paketa.
Naredba import dolazi neposredno iza naredbe package (ako ista uopšte postoji), ali obavezno
pre definicije bilo koje klase.
Opšti oblik:
import paket;
ili:
import paket1.*;
ili:
66
import paket1.paket2.*;
…
ili:
import paket1.klasa;
Ako umesto imena klase stavimo *, to znači da hoćemo da uvezemo ceo paket.
npr: import java.lang.*
Interfejsi
Koristeći ključnu reč interface, vršimo potpunu apstrakciju načina pristupa klasi – na taj način
možemo da odredimo šta klasa treba da radi, ali ne i kako to da radi. Sintaksa deklarisanja
interfejsa je vrlo slična deklaraciji klase, osim što interfejsi nemaju promenljive instanci (ne
možemo praviti objekte od njih), a njihove metode nemaju telo.
Kada klasa implementira neki interfejs, ona mora da definiše sve metode koje su deklarisane u
tom interfejsu, ali klasa slobodno određuje kako će realizovati te metode.
Da bi metoda u jednoj klasi mogla da bude pozvana iz druge, obe klase moraju postojati u
trenutku prevođenja kako bi prevodilac mogao da proveri da li su potpisi metoda kompatibilni.
Ovaj uslov zahteva stabilan, neproširiv skup klasa i tada je neizbežno da se funkcionalnost
programa potisne u vrh hijerarhije klasa kako bi bila dostupna što većem broju potklasa. Ovo se
prevazilazi pomoću interfejsa.Oni isključuju definicije metoda iz hijerarhije nasleđivanja.
Opšti oblik definicije:
[modifikator] interface imeInterfejsa
{
tip imeMetode1(listaParametara);
tip imeMetode2(listaParametara);
//…
final tip imePromenljive = vrednost;
//…
}
67
Opšti oblik implementacije interfejsa:
class imeKlase implements imeInterfejsa
{
//…
}
68
Izuzeci
Izuzetak (eng. exception) je u Javi objekat koji opisuje vanredno stanje, zapravo pogrešno stanje
koje se pojavljuje u trenutku izvršavanja programa. Kada nastane takvo vanredno stanje, stvara
se objekat koji predstavlja izuzetak i ubacuje se u metodu koja je izazvala grešku. Ta metoda
može sama da obradi grešku ili da je prosledi dalje. U svakom slučaju, izuzetak biva uhvaćen i
obrađen.
Za obradu izuzetaka koristimo 5 rezervisanih reči:
try, catch, throw, throws, finally
Kratak opis:
Unutar bloka try smeštaju se programske naredbe u toku čijeg izvršavanja može doći do
izuzetaka. Program hvata izuzetak pomoću naredbe catch i pokušava da ga obradi na neki
racionalan način. Javin izvršni sistem automatski izaziva izuzetke koji se osdnose na sistemske
greške. Kada želimo ručno da izazovemo izuzetke, koristimo ključnu reč throw. Ako za neki
izuzetak ne želimo da se obrađuje unutar metode u kojoj je izazvan, možemo ga izbaciti iz te
metode i njegovu obradu prepustiti metodi koja je pozvala trenutnu. Tip izuzetka koji može biti
izbačen metodom moramo označiti pomoću reči throws. U blok finally stavljamo naredbe koje
svakako moraju da se izvrše pre nego što se metoda vrati u akciju.
Izgled opšteg bloka za obradu izuzetaka:
try
{
//blok koda koji prati pojavu gresaka
}
catch(TipIzuzetka1 exOb)
{
//obrada izuzetka tipa TipIzuzetka1
}
catch(TipIzuzetka2 exOb)
{
//obrada izuzetka tipa TipIzuzetka2
}
//…
finally
{
//blok koda koji mora da se izvrsi pre kraja bloka try
}
69
Tipovi izuzetaka
Svi tipovi izuzetaka su potklase ugrađene klase Throwable – ta klasa je na vrhu hijerarhije klasa
izuzetaka. Neposredno ispod nje su dve potklase koje dele izuzetke na dve velike grupe. Jedna
potklasa je Exception – ona se odnosi na vanredna stanje koja treba da uhvate korisnički
programi. U toj klasi pravimo potklase za posebne vrste izuzetaka. Jedna njena vrlo važna
potklasa je klasa RuntimeException. Izuzeci ovog tipa se automatski definišu za programe koje
pišemo i obuhvataju, npr. deljenje nulom, neipsravno indeksiranje nizova itd.
Druga grupa izuzetaka nasleđuje klasu Error – to su izuzeci za koje se ne očekuje da će ih naš
program uloviti. Ova se klasa koristi za označavanje grešaka koje se odnose na samo okruženje
prilikom izvršavanja programa, npr. prekoračenje steka.
Neuhvaćeni izuzeci
Svaki izuzetak koji ne bude uhvaćen našim programom, na kraju će obraditi standardni
obrađivač. On prikazuje text sa opisom izuzetka, ispisuje stanje steka za metode od trenutka
nastanka izuzetka i završava program.
Primer:
public class exc0 {
public static void main(String args[])
{
int d = 0;
int a = 4/d;
}
}
Posle pokretanja:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at exc0.main(exc0.java:5)
Stanje steka: ime klase: exc0, ime metode: main, ime datoteke: exc0.java i broj programskog
reda u kojem je nastao izuzetak: 5.
Tip bačenog izuzetka je potklasa klase Exception i zove se ArithmeticException.
Korišćenje try i catch
Ako želimo da presretnemo i obradimo grešku u trenutku izvršavanja programa, naredbe koje
želimo da nadgledamo smestićemo unutar bloka try. Neposredno iza bloka try, koristimo
naredbu catch u kojoj naznačavamo koji tip izuzetka želimo da uhvatimo.
70
Primer:
public class exc2 {
public static void main(String args[])
{
int d, a;
try
{
d = 0;
a = 10/d;
System.out.println("Ovo se nece odstampati!");
}
catch(ArithmeticException e)
{
System.out.println("Deljenje nulom!");
}
System.out.println("Posle odredbe catch stampaj ovo.");
}
}
Izlaz:
Deljenje nulom!
Posle odredbe catch stampaj ovo.
Kada dođe do izuzetka, kontrola programa se sa bloka try prenosi na blok catch, tj. catch se
poziva tako da se izvršavanje nikada ne vraća na blok try. Pošto se izvrši catch, izvršavanje se
nastavlja prvom naredbom koja sledi neposredno posle celog try/catch bloka.
try i catch naredba čine jednu jedinstvenu celinu, što znači da se važenje odredbe catch proteže
samo na iskaze iz prve prethodne naredbe try. Catch ne može da uhvati izuzetak koji baca neka
druga naredba try osim u slučaju ugnježdenih try naredbi. Naredbu try ne možemo koristiti
samostalno.
Primer4: U svakoj iteraciji for petlje dobijamo 2 slučajna cela broja. Jedan ceo broj delimo
drugim, a zatim se dobijenim rezultatom deli broj 12345. Konačan rezultat se dodeljuje
promenljivoj a. Ako bilo koja od operacija prouzrokuje grešku deljenja nulom, greška se
obrađuje tako što se vrednost promenljive a podešava na nulu, a program nastavlja sa radom kao
da se ništa nije desilo.
Prikaz opisa izuzetka
U klasi Throable redefinisana je metoda ToString(), tako da vraća text sa opisom izuzetka.
Primer, dodatak u prethodni primer:
71
catch(ArithmeticException e)
{
System.out.println("Izuztek: " + e);
a=0;
}
Izlaz:
…
Izuztek: java.lang.ArithmeticException: / by zero
Više odredaba catch
Ponekad isti blok naredbi može da izazove više izuzetaka različitog tipa. U tom slučaju koristimo
više odredaba catch, po jednu za hvatanje svakog tipa izuzetka. Kada dođe do izuzetka, pregleda
se svaka catch odredba i izvršava se prva koja po tipu odgovara izuzetku. Kada se jedna catch
odredba izvrši, ostale se preskaču i izvršavanje se nastavlja posle try/catch bloka.
public class DvaTipaIzuzetaka {
public static void main(String args[])
{
try
{
int b = 33/0;
//int b = 33/1;
int c[] = new int[42];
c[42] = 99;
}
catch (ArithmeticException e)
{
System.out.println("Deljenje nulom: " + e);
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Indeks niza izvan oblasti vazenja:" + e);
}
System.out.println("Posle blokova try/catch");
}
}
Ispisaće:
Deljenje nulom: java.lang.ArithmeticException: / by zero
Posle blokova try/catch.
72
A kada pokrenemo sa zakomentarisanim prvim redom:
public class DvaTipaIzuzetaka {
public static void main(String args[])
{
try
{
//int b = 33/0;
int b = 33/1;
int c[] = new int[42];
c[42] = 99;
}
catch (ArithmeticException e)
{
System.out.println("Deljenje nulom: " + e);
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Indeks niza izvan oblasti vazenja:" + e);
}
System.out.println("Posle blokova try/catch.");
}
}
Ispisaće:
Indeks niza izvan oblasti vazenja:java.lang.ArrayIndexOutOfBoundsException: 42
Posle blokova try/catch.
73
Ugnježdena naredba try
Try može da bude ugnježdena, tj. može da se nađe unutar drugog bloka try. Svaki put kad
program započne naredbu try, na stek se stavi kontekst odgovarajućeg izuzetka. Ako unutrašnja
naredba try ne obrađuje određeni izuzetak, stek se NE prazni i očekuje se da će izuzetak preuzeti
catch blok spoljne naredbe try. Ovo se ponavlja sve dok se ne pronađe jedna od naredaba catch
koja hvata taj tip izuzetka ili se ne iscrpu sve ugnježdene naredbe try. Ako nijedna naredba catch
ne obradi izuzetak, obradiće ga javin izvršni sistem.
Primer – različit broj argumenata iz komandne linije:
public class UgnjezdeniTry {
public static void main(String args[])
{
try
{
int a = args.length;
/*
Ukoliko u komandnoj liniji nema argumenata,
sledeca naredba ce izazvati izuzetak deljenja nulom
*/
int b = 45 / a;
System.out.println("a = " + a);
try //ugnjezdeni try blok
{
/*
Ukoliko se u komandnoj liniji pojavi jedan argument,
sledeca naredba ce izazvati izuzetak deljenja nulom
*/
if(a==1)
a = a/(a-a); //deljenje nulom
/*
Ukoliko se u komandnoj liniji pojave dva argumenta,
nastace izuzetak prekoracenja oblasti vazenja
*/
if(a==2)
{
int c[] = new int[3];
c[4] = 6;
}
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Indeks niza izvan oblasti vazenja:" + e);
}
}
74
catch (ArithmeticException e)
{
System.out.println("Deljenje nulom: " + e);
}
}
}
C:\Documents and Settings\Xenia\workspace\Izuzeci\bin>java UgnjezdeniTry
Deljenje nulom: java.lang.ArithmeticException: / by zero
C:\Documents and Settings\Xenia\workspace\Izuzeci\bin>java UgnjezdeniTry 1
a=1
Deljenje nulom: java.lang.ArithmeticException: / by zero
C:\Documents and Settings\Xenia\workspace\Izuzeci\bin>java UgnjezdeniTry 1 2
a=2
Indeks niza izvan oblasti vazenja:java.lang.ArrayIndexOutOfBoundsException: 4
Rezervisana reč throw
Naš program može da baci određeni izuzetak pomoću naredbe throw. Opšti oblik naredbe je:
throw InstancaTipaThrowable;
Pri čemu InstancaTipaThrowable mora da bude objekat tipa Throwable ili potklasa ove klase. Za
izuzetka ne možemo koristiti proste tipove (int, char…) niti klase izvan klase Throwable, npr
String, Object… Objekat tipa Throwable možemo da dobijemo na dva načina: pomoću
parametara u odredbi catch i pomoću operatora new.
Tok izvršavanja se zaustavlja neposredno iza naredbe throw – ne izvršava se nijedna nareba
posle toga. Pregleda se najbliži blok try i traži odredba catch koja odgovara tipu izuzetka. Ako se
ona pronađe, kontrola izvršavanje se prebacuje na tu naredbu. Ukoliko se ona ne pronađe,
pregleda se sledeći blok try itd. Ako se uopšte ne pronađe odgovarajuća odredba catch,
standardni obrađivač izuzetaka preuzima kontrolu.
75
Naredba throws
Ako pravimo metodu koja može da izazove izuzetak koji neće sama obraditi, moramo naznačiti
takvo ponašanje, kako bi funkcije koje pozivaju tu našu metodu mogle da se zaštite od tog
izuzetka. U ovu svrhu, u deklaraciju metode uključujemo rezervisanu reč throws. Odredba
throws nabraja tipove izuzetaka koje metoda može da baca, osim izuzetaka tipa Error i
RuntimeException ili njihovih potklasa.
Opšti oblik deklaracije:
tip ImeMetode(listaParametara) throws listaIzuzetaka
{
//telo metode
}
pri čemu listaIzuzetaka sadrži spisak tipova izuzetaka koje metoda može da baca, razdvojenih
zarezima. Ako metoda baca izuzetak, a to ne navedemo u deklaraciji, kompajler prijavljuje
grešku.
Rezervisana reč finally
Kada metode bacaju izuzetke, njihovo izvršavanje se više ne odvija linearno, npr. ponekad
izuzetak izazove trenutni izlazak iz metode. Ponekad ovo može da stvori problem – npr. ako
metoda na početku otvara neku datoteku, onda bismo želeli i da se ta datoteka zatvori pre nego
što se program završi. Za sprečavanje ovakvih problema, koristimo naredbu finally.
Naredba finally obrazuje blok naredbi koji se izvršava neposredno po završetku try/catch bloka,
a pre prve naredbe koja sledi iza tog bloka. Finally blok se izvršava bez obzira da li je izuzetak
bačen ili ne. Čak i ako je izizetak bačen, a ne postoji catch blok koji ga hvata, finally blok se
izvršava. Takođe, ovaj blok se izvršava i neposredno pre izlaska iz svake metode koja se vraća
pozivaocu iz bloka try/catch. Ova odredba nije obavezna, ali za svaku try naredbu neophodno je
da postoji bar jedna od naredbi catch ili finally.
Javini ugrađeni izuzeci
U standardnom paketu java.lang, Java definiše više klasa izuzetaka. Većina predstavlja potklase
tipa RuntimeException, a pošto se java.lang paket podrazumevano uvozi u sve programe, ove
izuzetke nije potrebno unositi u throws listu. Ovi izuzeci se nazivaju neproveravani izuzeci. Za
razliku od njih, sve ostale, takozvane proveravane izuzetke, potrebno je uneti u throws listu.
76
Neki neproveravani izuzeci:
Exceptions
Meaning
ArithmeticException
Arithmetic error, such as divide-by-zero.
ArrayIndexOutOfBoundsException
ArrayStoreException
Array index is out-of-bounds.
Assignment to an array element of an incompatible type.
ClassCastException
Invalid cast.
IllegalArgumentException
Illegal argument used to invoke a method.
IllegalMonitorStateException
unlocked thread.
Illegal monitor operation, such as waiting on an
IllegalStateException
Environment or application is in incorrect state.
IllegalThreadStateException
thread state.
Requested operation not compatible with current
IndexOutOfBoundsException
Some type of index is out-of-bounds.
NegativeArraySizeException
Array created with a negative size.
NullPointerException
Invalid use of a null reference.
NumberFormatException
Invalid conversion of a string to a numeric Format
SecurityException
Attempt to violate security.
StringIndexOutOfBounds
Attempt to index outside the bounds of a string
UnsupportedOperationException
An unsupported operation was encountered
Neki proveravani izuzeci:
Exception
Meaning
ClassNotFoundException
Class not found.
CloneNotSupportedException
Cloneable interface.
Attempt to clone an object that does not implement the
77
IllegalAccessException
Access to a class is denied.
InstantiationException
interface.
Attempt to create an object of an abstract class or
InterruptedException
One thread has been interrupted by another thread.
NoSuchFieldException
A requested field does not exist.
NoSuchMethodException
A requested method does not exist
Pravljenje sopstvenih izuzetaka
Ako želimo da pravimo sopstvene tipove izuzetaka, koji će razrešavati specijalne sitaucije u
našim programima, potrebno je samo da definišemo potklasu klase Exception. Ova klasa
naslešuje metode klase Throwable, koje možemo predefinisati onako kako nama odgovara.
78
Javine kolekcije
Paket java.util između ostalog sadrži i jedan od najmoćnijih javinih podsistema – sistem rada sa
kolekcijama (Collections Framework). Kolekcije predstavljaju sofosticiranu hijerarhiju klasa i
interfejsa koje predstavljaju sam vrh tehnologije rada sa objektima.
Javin princip rada sa kolekcijama propisuje način na koji programi rade sa grupama objekata, a
uspostavljen je radi ostvarenja nekoliko ciljeva. Pre svega, potrebno je postići visoku efikasnost
rada. Realizacija osnovnih kolekcija (dinamički nizovi, povezane liste, stabla i heš tabele) vrlo je
efikasna i uglavnom nemamo potrebu da ručno programiramo neki od ovih kolekcija za
smeštanje podataka. Zatim, obezbeđen je saglasan rad različitih tipova kolekcija i visok stepen
njihove saradnje. Treće, obezbeđeno je lako proširivanje i prilagođavanje kolekcija.
Zbog svega ovoga, jedinstveni princip rada sa kolekcijama izgrađen je na skupu standardnih
interfejsa. Postoji veliki broj interfejsa koje možemo odmah upotrebiti, zatim možemo pisati i
svoje klase kolekcija, a postoje i mehanizmi pomoću kojih standardne nizove možemo uklopiti u
kolekcije.
Druga važna grupa mahanizama za rad sa kolekcijama su algoritmi. Oni obavljaju operacije nad
kolekcijama i definisani su kao statične metode unutar klase Collections. Kako je ovo osnovna
klasa koju nasleđuju sve kolekcije, algoritmi su dostupni svim kolekcijama, pa nijedna klasa ne
mora da realizuje sopstvenu verziju.
Sa kolekcijama je blisko povezan interfejs Iterator. On nudi univerzalan, standradizovan način
pristupanja pojedinačnim elementima kolekcije i omogućava prebrojavanje sadržaja kolekcije.
Pošto svaka kolekcija realizuje interfejs Iterator, elementima svake klase kolekcije može da se
pristupi pomoću metoda definisanih ovim interfejsom.
Sve klase kolekcija nasleđuju interfejs Iterable, koji donosi mogućnost korišćenja for-each
verzije petlje for, koja umnogome zamenjuje upotrebu iteratora.
Interfejs Collection
Interfejs Collection je kamen temeljac na kome su izgrađeni principi rada sa kolekcijama, jer ga
mora realizovati svaka klasa koja definiše kolekciju. Collection se deklariše na sledeći način:
interface Collection <E>
E označava tip objekata koje će kolekcija sadržati. Ovaj interfejs deklariše osnovne metode koje
ima svaka kolekcija. Osnovne metode su:
boolean add(E obj)
Dodaje obj u kolekciju. Vraća true ako je operacija uspela, a ako je obj već član kolekcije ili
kolekcija ne dozvoljava duplikate, vraća false.
79
boolean addAll(Collection kolekcija)
Pozivajućoj kolekciji dodaje sve elemente kolekcije.
void clear()
Uklanja sve elemente iz kolekcije.
boolean contains(Object obj)
Vraća true ako je obj element kolekcije, inače vraća false.
boolean containsAll(collection kolekcija)
Vraća true ako kolekcija sadrži sve elemente “kolekcije”, inače false.
boolean equals(Object obj)
Vraća true ako su obj i kolekcija ekvivalentni, inače vraća false.
int hashCode()
Vraća ključ za heširanje kolekcije.
boolean isEmpty()
Vraća true ako je kolekcija prazna, inače vraća false.
Iterator <E> iterator()
Vraća iterator za pozivajuću kolekciju.
boolean remove(Object obj)
Uklanja jednu instancu objekta obj iz kolekcije.
boolean removeAll(Collection kolekcija)
Iz kolekcije “kolekcija” ukljanja sve elemente.
boolean retainAll(Collection kolekcija)
Iz kolekcije ukljanja sve elemente osim elemenata “kolekcije”.
int size()
Vraća broj elemenata u kolekciji.
Object[] toArray()
80
Vraća niz koji sadrži sve elemente kolekcije. Elementi niza su kopije elemenata kolekcije.
Interfejs List
Ovaj interfejs proširuje interfejs Collection i deklariše ponašanje kolekcije koja sadrži sekvencu
elemenata. Elementi se mogu umetati ili im se može pristupati prema njihovom položaju u listi,
pri čemu indeksiranje počinje od nule. Lista može da sadrži duplikate elemenata. Liste se
deklarišu pomoću:
interface List<E>
gde je E tip objekata koje će lista sadržati.
Klasa ArrayList
Ova klasa je potklasa klase AbstractList i realizuje interfejs List. Klasa ArrayList podržava
dinamičke nizove koji po potrebi mogu da rastu. Standardni nizovi u Javi su fiksne dužine. Kada
ih napravimo, ne možemo da ih smanjujemo ili povećavamo, što znači da unapred moramo da
znamo broj elemenata. Problem može da bude ako takav podatak nemamo sve do trenutka
izvršavanja programa. Za rešavanje ovog problema sa kolekcijama, predviđena je klasa
ArrayList. Ona u suštini predstavlja niz promenljive dužine koji sadrži reference objekata. Dakle,
objekat ArrayList može dinamički da menja svoju velicinu.
Klasa ima sledeće konstruktore:
ArrayList()
ArrayList(Collection kolekcija)
ArrayList(int kapacitet)
Pristupanje kolekciji pomoću iteratora
Iteratori su objekti kojei realizuju interfejs Iterator ili ListIterator. Interfejs Iterator omogućava
da prolazimo kroz kolekciju i da očitavamo ili uklanjamo elemente iz nje, a ListIterator proširuje
Iterator i omogućava prolazak kroz listu u oba smera i menjanje elemenata. Svaka od klasa
kolekcija ima metodu iterator(), koja vraća iterator, što pokazuje na početak kolekcije. Pomoću
ovog iteratora možemo da pristupamo svakom element kolekcije pojedinačno. Da bismo koristili
iterator za prolazak kroz kolekciju, potrebno je da uradimo sledeće:
1. Preuzmemo iterator koji pokazuje na početak kolekcije tako što pozovemo metodu
iterator().
2. Uspostavimo petlju koja treba da se vrti sve dok metoda hasNext() vraća vrednost true.
3. Pozivamo metodu next() unutar petlje da bismo dobili reference na sledeći element
kolekcije.
81
For-each kao alternativa iteratorima
Ako ne želimo da menjamo sadržaj kolekcije ili elemente kolekcije nećemo da očitavamo
obrnutim redosledom, za prozivanje elemenata kolekcije, od iteratora je čecto pogodnija for-each
verzija petlje for.
Primer: Sabiranje iznosa objekata kolekcije.
import java.util.ArrayList;
public class PrimerForEach {
public static void main(String args[])
{
ArrayList<Integer> brojevi = new ArrayList<Integer>();
brojevi.add(1);
brojevi.add(2);
brojevi.add(3);
brojevi.add(4);
brojevi.add(5);
System.out.println("Prvobitni sadrzaj liste bojevi: ");
for(int b : brojevi)
System.out.println(b + " ");
System.out.println();
//Sabiranje brojeva
int zbir = 0;
for(int b : brojevi)
zbir += b;
System.out.println("Zbir bojeva je: " + zbir);
}
}
82
Apleti
Apleti su male aplikacije smeštene na serveru koje se prenose preko interneta, a zatim
automatski instaliraju kod klijenta i izvršavaju kao deo Web dokumenta. Aplet ima ograničen
pristup resursim klijenta, tako da može da napravi proizvoljno multimedijalno okruženje i i da
izvršava složena izračunavanja, bez opasnosti da će u sistem uneti neki virus ili narušiti integritet
podataka.
Svi apleti moraju da budu potklase klase Applet. Prema tome, svi moraju da uvezu paket
java.applet. Interakciju sa korisnikom apleti ne ostvaruju preko konzole, već koriste grafičku
biblioteku Abstract Window Toolkit (AWT). Ova biblioteka pruža mogućnost rada u grafičkom
okruženju zasnovanom na prozorima. Zato je osim paketa java.applet neophodno uvesti i paket
java.awt.
Aplet ne sadrži metodu main() – zapravo samo mali broj apleta realizuje ovu metodu. Apleti
počinju da se izvršavaju kada se ime njihove klase prosledi programu za prikazivanje apleta ili
čitaču Weba. Postoje 2 načina za izvršavanje apleta:
1. Unutar čitača Weba kompatibilnog sa Javom
2. Pomoću programa za prikazivanje apleta, na primer standardnog programa apletviewer.
Takav program izvršava aplet u prozoru i najbrži je, odnosno najlakši način, da
proverimo aplet.
Svi apleti, osim najjednostavnijih, redefinišu skup osnovnih metoda pomoću kojih čitač ili
program za prikazivanje rade sa apletom i upravljaju njegovim izvršavanjem. Četiri od tih
metoda definisane su kasom Applet:
init()
start()
stop()
destry()
Još jedna od njih, metoda paint() definisana je AWT klasom Component. Osnovna struktura
apleta je ovakva:
//Struktura apleta
import java.awt.*;
import java.applet.*;
public class KosturApleta extends Applet{
//Ova metoda ce prva biti pozvana
public void init()
83
{
//inicijalizacija
}
/*Ova metoda ce biti pozvana posle init(). Poziva se i svaki put
* kada se aplet ponovo aktivira.
*/
public void start()
{
//zapocinje ili nastavlja sa izvrsavanjem
}
//poziva se prekidanje rada apleta
public void stop()
{
//prekida izvrsavanje
}
/*Pozivamo prilikom zavrsavanja rada apleta.
* Ovo je poslednja metoda koja se izvrsava.*/
public void destroy()
{
//izvodi zavrsne operacije
}
//Pozivamo kada treba osveziti prikaz rada apleta
public void paint(Graphics g)
{
//osvezava sadrzaj prozora
}
}
Obrada slika
Paket java.awt.image obezbeđuje podršku za rad sa slikama. Sa stanovišta jave slika je grafički
objekat pravougaonog oblika i predstavljaju ključni element dizajniranja web stranica. Slike
moraju biti u GIF ili JPEG formatu.
Najznačajnije metode koje se koriste za obradu slika su getImage koja služi za učitavanje slike i
drawImage koja služi za prikazivanje slike, a obe imaju nekoliko potpisa, od kojih se najčešće
koriste:
84
Image getImage(URL urlAdresa)
Image getImage(URL urlAdresa, String imeSlike)
boolean drawImage(Image imgObj, int levo, int gore, ImageObserver imgOb)
Klasa Image u Javi koristi se za pravljenje reference na slike u memoriji ili za slike koje se
moraju učitati iz spoljnih izvora. Nasuprot većini drugih objekata, slika se u Javi ne može
napraviti pomoću standardnog konstruktora, npr:
Image test = new Image(100, 200);
jer klasa Image nema dovoljno podataka o svom okruženju da bi napravila odgovarajući format
za prikazivanje na ekranu. Zbog toga klasa Component iz java.awt paketa ima metodu
createImage() koja se koristi za pravljenje objekata ove klase.
MediaTracker je još jedna klasa koju koristimo u primeru da bismo kontrolisali učitavanje slike.
Objekti ove klase paralelno proveravaju stanje učitavanja proizvoljnog broja slika.
Korišćenje kontrolnih objekata
Najčešće korišćeni kontrolni objekat je dugme. Dugme (Button) predstavlja komponentu koja
sadrži natpis i koja generiše događaj kada se pritisne. Dugmad su objekti tipa Button. Ova klasa
ima 2 konstruktora:
Button()
Button(String str)
Natpis na dugmetu zadaje metoda setLabel(), a tekući natpis vraća metoda getLabel().
Polje za potvrdu (Checkbox) je kontrolni objekat koji se koristi za uključivanje i isključivanje
neke opcije. Sastoji se od malog okvira u kojem postoji ili ne postoji znak za potvrdu. Sa svakim
poljem za potvrdu, povezan je natpis koji opisuje šta to polje predstavlja. Polja za potvrdu se
mogu koristiti samostalno ili kao deo grupe.
Moguće je napraviti grupu međusobno isključivih polja za potvrdu od kojih u jednom trenutku
može biti potvrđeno jedno i samo jedno polje. Ova polja za potvrdu često se nazivaju i radiodugmad.
Klasa Choice se koristi za pravljenje iskačućih lista (pop-up liste) sa stavkama koje korisnik
može da izabere. Metodom add dodajemo stavku u listu. Njen oblik je:
void add(string ime)
Metode getSelectedItem() i getSelectedIndex() vraćaju ime i index trenutno izabrane stavke, a
njihovi potpisi su:
85
String getSelectedItem()
int getSelectedIndex()
Metoda getItemCount() vraća broj stavki u listi. Metoda select() postavlja trenutno izabranu
stavku. Ime stavke pridružene nekom indeksu vraća metoda getItem():
String getItem(int indeks)
Sve ove komponente razmešta podrazumevani raspoređivač. Raspoređivač (Layout manager)
automatski razmešta kontrolne objekte u prozoru po određenom principu. Raspoređivač je
instanca klase koja realizuje interfejs LayoutManager. Raspoređivač možemo promeniti
metodom setLayout. Oblik ove metode je:
void setLayout(LayoutManager rasporedjivac)
Klasa BorderLayout realizuje uobičajen stil izgleda prozora najvišeg nivoa. Ona u uglovima ima
4 uske oblasti nepromenljive širine i jednu veliku oblast u sredini. Četiri strane se označavaju
kao sever, jug, istok i zapad. Središnja oblast se označava kao centar.
Obrada događaja
Apletima upravljaju događaji, pa je iz tog razloga, obrada događaja srž uspešnog programiranja
apleta. Većina događaja na koje aplet reaguje potiče od aktivnosti korisnika. Ti događaji se na
različite načine prosleđuju apletima, zavisno od vrste samog događaja. Događaji na koje se
najčešće reaguje su oni koje generišu miš, tastatura i različiti kontrolni objekti, kao što su
dugmad. Klase i interfejsi koji su vezani za obradu događaja u apletima nalaze se u paketu
java.awt.event.
Moderan pristup obradi događaja zasniva se na modelu prosleđivanja događaja koji definiše
standardne mehanizme za generisanje i obradu događaja. Koncept je jednostavan: izvor (source)
generiše događaj i šalje ga ka jednom ili više prijemnika (listener). U ovakvom pristupu
prijemnik pasivno čeka obaveštenje o događaju, a kada prihvati događaj, obrađuje ga i daje
odgovor. Na ovaj način logika aplikacije koja obrađuje događaj potpuno je odvojena od logike
korisničkog okruženja koja generiše te događaje.
Događaj je objekat koji opisuje stanje promene izvora.
Izvor je objekat koji generiše događaj. Jedan izvor može da generiše više vrsta događaja. Izvor
mora da registruje prijemnike kako bi oni mogli da prime informacije o određenoj vrsti događaja.
Svaka vrsta događaja ima svoju metodu registrovanja, čiji je opšti oblik:
public void addVrstaListener(VrstaListener el)
gde Vrsta predstavlja ime događaja, a el referencu na prijemnik događaja. Na primer:
addKeyListener() ili addMouseMotionListener().
86
Prijemnik (listener) je objekat koji dobija obaveštenje o odigravanju događaja. Da bi objekat bio
prijemnik, mora da ispuni 2 osnovna uslova:
1. mora da bude registrovan kod jednog ili više izvora kako bi primao obaveštenja o
određenim vrstama događaja
2. mora da realizuje metode za prijem i obradu tih obaveštenja
Klase događaja
Na vrhu hijerarhije događaja je klasa EventObject koja se nalazi u paketu java.util. Još jedna
važna klasa je AWTEvent, koja je natklasa svih AWT događaja koji koriste model prosleđivanja.
Paket java.awt.event definiše nekoliko vrsta događaja. Neki od najvažnijih su:
1. ActionEvent (nastaje kada se pritisne taster miša, kada se 2 puta pritisne stavka sa liste ili
kada se izabere stavka menija)
2. AdjustmentEvent (nastaje kada se radi sa trakom za pomeranje saržaja)
3. ComponentEvent (nastaje kada komponenta postane nevidljiva, pomeri se, promeni joj se
veličina ili postane vidljiva)
4. ContainerEvent (nastaje kada se komponenta smešta u kontejner ili uklanja iz njega)
5. FocusEvent (nastaje kada komponeneta dobije ili izgubi fokus preko tastature)
6. InputEvent (apstraktna natklasa za sve ulazne klase događaja kod komponenata)
7. ItemEvent (nastaje kada se pritisne mišem polje za potvrdu ili stavka sa liste; nastaje i
kada se izabere jedna od ponuđenih opcija, odnosno poništi njen izbor)
8. KeyEvent (nastaje kada se ulazni podatak primi sa tastature)
9. MouseEvent (nastaje kada se miš prevuče, pomeri, taster miša pritisne ili otpusti; nastaje
i kada pokazivač miša dođe na komponentu ili je napusti)
10. TextEvent (nastaje kada se izmeni vrednost u prostoru ili polju za text)
11. WindowEvent (nastaje kada se prozor aktivira, zatvori, deaktivira, pretvori u ikonicu ili
razvije iz ikonice, otvori ili napusti)
Interfejsi prijemnika događaja
Definisani su takođe u paketu java.awt.event i odgovaraju klasama događaja, a najčešće
kotišćeni su:
1. ActionListener (definiše metodu actionPerformed())
2. AdjustmentListener
3. ComponentListener
4. ContainerListener
5. FocusListener
6. ItemListener (definiše metodu itemStateChanged())
7. KeyListener (definiše metode keyPressed(), keyReleased(), keyTyped())
8. MouseListener (definiše metode mouseClicked(), mouseEntered(), mouseExited(),
mousePressed(), mouseReleased() )
9. MouseMotionListener(definiše metode mouseDragged(), mouse Moved())
10. TextListener
87
Download

Osnovni kurs - WordPress.com