JAVA - PROGRAMIRANJE ZA INTERNET

  1. Povijest Jave
  2. Osnovna svojstva Jave
  3. Java programi
  4. Java i C
  5. Java Virtual Machine

 

Literatura: 

Dario Sušanj: Java, Znak, Zagreb 1997.

http://java.sun.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1. Povijest Jave

Java je najznačajnije što se dogodilo nakon pojave samog Weba. Donijela je dinamičnost na, do tada prilično statičke, Web stranice. Ona omogućava autorima Web stranica i programerima da napišu aplikaciju koja će se izvršavati unutar samog pretraživačkog programa. Tako se mogu pisati programčići kojima će se jednostavno uljepšati izgled Web stranice, ali i potpune distribuirane aplikacije koje se izvršavaju na Webu i u drugim umreženim okružjima.

Početkom 1991. grupa Sunovaca nastojala je osmisliti jedinstveni jezik kojim će se programirati svi elektronički uređaji koji u sebi sadrže mikroprocesore – televizori, video-uređaji, glazbene linije, satelitske antene, pa čak i mikrovalne pećnice, strojevi za pranje rublja, tosteri i dr. U Sunu su počeli s projektom Green. Njegov cilj je bio stvaranje platformski nezavisnog jezika, koji će se izvršavati na različitim tipovima mikroprocesora. Projektom su željeli razviti jezik kojim će moći napisati aplikaciju koja pokreće televizor ili toster, a da se ona nakon toga može izvršavati na svim tipovima procesora koje u takve uređaje ugrađuju razni proizvođači.

Java je predstavljena u svibnju 1995. na sajmu SunWorld’95, četiri godine nakon početka razvijanja projekta, a konačnu verziju Sun je službeno predstavio u siječnju 1996. označenu brojkom 1.0. Godinu dana kasnije, nakon uklanjanja određenih nedostataka, Sun je objavio i novu verziju Jave, 1.1.

2. Osnovna svojstva Jave

Java je jednostavan, objektno-orijentiran, distribuiran, interpretivan, robustan, siguran, prenosiv, visokoučinkovit, višenitan i dinamički programski jezik.

Jednostavnost jezika očituje se u tome da ga programeri mogu brzo naučiti, jer je broj stvari koje treba upamtiti vrlo malen. Autorima Jave bio je cilj učiniti je što sličnijom programskim jezicima koje većina programera već dobro poznaje.

Objektna-orijentiranost znači da se kao programer možemo usredotočiti na podatke (objekte) i metode (klase – skup metoda) pomoću kojih ćemo obaviti neki posao, a da ne moramo uvijek samo voditi brigu o tome kako ćemo napisati pojedine dijelove programa.

Distribuiranost – Java ima ugrađene sve osnovne funkcije za rukovanje mrežnim protokolima. Uz nju dobivamo biblioteke klasa koje komuniciraju s protokolima TCP/IP, FTP i HTTP. Zahvaljujući ovoj ugrađenoj mrežnoj podršci, programi pisani u Javi mogu bez problema pristupati podacima koji su pohranjeni širom Interneta na različitim tipovima poslužitelja. Budući da je zamišljena tako da podrži postojeće mrežne resurse za Javu kažemo da je distribuirana.

Prenosivost i interpretiranje – Za razliku od kompiliranih jezika, kod kojih se iz izvornog koda odmah stvara izvršiva verzija programa namijenjena određenoj računalnoj platformi, prevođenje i izvršavanje Java aplikacija podijeljeno je u dvije faze. U prvoj Java kompilator iz izvornog koda programa stvara bajt-kod. Bajt-kod bismo mogli nazvati “izvršnom” verzijom programa, iako se ne izvršava pod nadzorom operativnog sustava nekog računala niti je posebno kompilirana za njega. Umjesto toga, bajt-kod je međukod koji se pokreće pod nadzorom Javinog izvršnog sustava. Taj izvršni sustav interpretira bajt-kod i prevodi njegove naredbe u naredbe specificirane za računalo na kojem se izvršava aplikacija. Upravo zbog toga što se prevođenje programa iz bajt-koda u jezik platforme (strojni jezik) obavlja tijekom izvršavanja programa, Java se smatra interpretiranim jezikom.

Da bi se Java prenijela na neku novu platformu, potrebno je samo napisati izvršni sustav za nju. Izvršni sustav susrest ćemo pod imenom Java Virtual Machine (prividni stroj za Javu). Taj prividni stroj nije ništa drugo do okolina unutar koje se izvršavaju Java aplikacije. Možemo ga zamisliti kao “računalo u računalu” koje pokreće samo Java programe. Izvršni sustav može, ako je ispravno prenesen na novu platformu, izvršavati sve Java aplikacije, bez obzira na to tko ih je i na kojem računalu napisao. Izvršni sustav ugrađuje se u pretraživačke programe kako bi mogli pokretati programe pisane u Javi, a čak i neki operativni sustavi imaju ugrađen izvršni sustav i mogu pokrenuti Java aplikaciju poput bilo koje druge aplikacije pisane i kompilirane za taj sustav. Java aplikacija ne mora se pritom niti najmanje mijenjati ili prilagođavati; ona se mrežom distribuira u svom bajt-kod obliku, a izvršni sustav je tijekom izvršavanja prevodi u specifične naredbe koje razumije računalo za koje je izvršni sustav napisan.

Robusnost – Budući da je bila namijenjena pisanju aplikacija koje će se izvršavati u uređajima što se ubrajaju u potrošačku elektroniku, Java je zamišljena tako da bude vrlo sigurna i pouzdana. To, naravno, ne znači da se ne može napisati program bez pogrešaka. Budući da precizno određuje veličine pojedinih tipova podataka i da zahtijeva precizno deklariranje metoda, Java omogućava kompilatoru da pronalazi programske pogreške. Javin memorijski sustav sam vodi brigu o oslobađanju i zauzimanju memorije, a zbog nepostojanja pokazivača nemoguće je da programer sam piše po nedozvoljenoj memorijskoj lokaciji i tako uništi neke podatke. Spomenuti sustav automatskog prikupljanja memorijskog smeća otklanja pojavljivanje memorijskih rupa.

Sigurnost – Kada se govori o Javi i sigurnosti izvršavanja Java programa nameću se sljedeća pitanja: Je li moguće u Javi napisati virus? Može li program pisan u Javi učiniti štetu na računalu na kojem se izvršava? Je li moguće u program unositi izmjene nakon što je kompiliran u bajt-kod? Odgovor je: Java je vrlo sigurna! Interpreter provjerava ispravnost bajt-koda tijekom izvršavanja. Iako je kompilator napravio ispravan bajt-kod, interpreter ga još jednom provjerava kako bi zaista bio siguran da nitko s njime ništa nije radio ili ga mijenjao između kompiliranja i izvršavanja. Interpreter sprječava izvršavanje sumnjivog koda i koda koji bi sadržavao nedozvoljene radnje, poput pokušaja direktnog pristupa memoriji, nevažećih klasa, pogrešnih parametara koji se nalaze uz naredbe bajt-koda, pokušaja kršenja prava pristupa datotekama na disku ili nepravilnih pretvaranja među tipovima podataka.

Nakon što se uvjerio u ispravnost bajt-koda, interpreter određuje memorijski raspored klasa, osnovnih elemenata od kojih se gradi Java aplikacija. To je druga razina zaštite Java programa. Netko, tko bi želio izmjeniti kompilirani program u bajt-kodu, to ne može učiniti jer ne zna kako će klase biti raspoređene u memoriji.

Odličan učinak – Svaki programski jezik koji se zasniva na interpretiranju pati od sporosti, jer proces interpretiranja zahtijeva dosta procesorskog vremena za prevođenje samih naredbi, pa se time gubi na brzini izvršavanja. Unatoč sporosti, za većinu radnji koje obavljamo pomoću Jave – kao što su stvaranje korisničkih sučelja ili mrežne komunikacije – nije potrebna velika procesorska snaga. Aplikacija većinu svojeg vremena provodi besposlena, čekajući sljedeću naredbu korisnika ili pristizanje novih podataka s mreže.

Višenitnost – Java je trenutno jedini programski jezik koji podržava višenitno izvršavanje programa. Višenitnost omogućava programeru da unutar svog programa pokrene više niti izvršavanja i time ubrza rad programa. Primjerice, jedna nit može u pozadini obavljati složena preračunavanja, dok druga već prikuplja nove podatke od korisnika. Višenitno izvršavanje programa donosi i veću učinkovitost procesora, jer jedna nit može koristiti njegove resurse u trenucima dok je druga nit besposlena.

Dinamičnost – Java je dinamički jezik, kojem se bez problema mogu dodavati novi objekti. Tako se i svi programi pisani u Javi ponašaju potpuno dinamički. To u praksi mnogo znači i donosi najviše prednosto kod pretraživačkih programa. Ako program pisan u Javi ili pretraživački program pokuša pristupiti nekom novom tipu podatka za koji ne zna kako ga obraditi, program može zamoliti poslužitelja da mu pošalje klasu koja rukuje tim tipom podataka. Program u Javi sam će se dinamički nadograditi dobivenom klasom i obaviti željeni posao.

3. Java programi

Dva osnovna oblika Java programa jesu aplikacija i aplet. Aplikacija se smatra samostalni program koji se izvršava neovisno o pretraživačkom programu. Namjena tih aplikacija nije da budu ugrađene u Web stranice, već da se ponašaju jednako kao i sve ostale aplikacije na računalu. Java aplikacije se pokreću kao i ostali programi na računalu, ali zahtijevaju da je na njemu instaliran Javin izvršni sustav (Java Virtual Machine), koji takvu aplikaciju može pokretati. Za razliku od aplikacija, Java apleti su zamišljeni tako da “žive” na mreži, Internetu. Oni su složeniji od aplikacija. Izvršavaju se unutar Web stranice, pa je zato neophodan pretraživački program koji ih može pokrenuti. Zapravo, apleti su Java aplikacije koje se izvršavaju unutar pretraživačkog programa.

Budući da se apleti izvršavaju unutar Web pretraživača, njihovo je pisanje znatno lakše, jer se mogu više oslanjati na usluge pretraživača (kao što su otvaranje prozora i ispis grafike) nego što je to slučaj kod samostalnih aplikacija. Međutim, apleti su najčešće dodatno ograničeni time što smiju raditi na računalu na kojem se izvršavaju. Tako apleti obično uopće ne smiju pisati ili čitati datoteke na lokalnom disku, katkada ne mogu niti komunicirati s bilo kojim drugim računalom na Internetu osim s onim s kojeg su pozvani, a ne mogu niti pokretati druge aplikacije na lokalnom računalu. Zapravo, apleti sve ovo mogu raditi, ali je pitanje hoće li to dopustiti pretraživač.

Zbog različitosti svrhe jednog i drugog tipa Java aplikacija, razlikuje se i način pisanja njihovih osnovnih dijelova i način konačnog pokretanja i izvršavanja.

Aplikacije

Pisanje samostalne aplikacije u Javi svodi se na tri koraka:

  1. Upisivanje i spremanje izvornog koda
  2. Kompiliranje izvornog koda u bajt-kod pomoću kompilatora
  3. Pokretanje aplikacije pomoću interpretera bajt-koda

Primjer aplikacije: Ispisivanje tekstualne poruke na ekranu

class PrimjerJavaAplikacija {

public static void main (String args [ ]) {

System.out.println(“Moja prva aplikacija”);

}

}

Apleti

Apleti su Java programi koji se ugrađuju u Web stranicu, pa je i način njihova pisanja ponešto drugačiji. Životni vijek jednog apleta sastoji se od pet osnovnih faza:

- inicijalizacija

- pokretanje

- ispis na ekran

- zaustavljanje

- uništavanje.

Inicijalizacija je prva faza u životu jednog apleta. U toj se fazi aplet učitava u pretraživački program. Ona se događa samo jednom tijekom izvršavanja programa.

Faza pokretanja nastupa onda kada pretraživački program krene s izvršavanjem našeg programa. Pokretanje se događa kad korisnik prvi puta pristupi Web stranici na kojoj se nalazi aplikacija, te svaki sljedeći put kad se ponovno vrati na tu stranicu nakon što je posjetio još nekoliko stranica. Dakle, tijekom života jednog apleta faza pokretanja može nastupiti više od jedanput, za razliku od inicijalizacije koja se događa samo jednom.

Faza ispisivanja na ekran nastupa svaki put kada aplet želi ispisati ili nacrtati nešto u prozor pretraživačkog programa. Do ispisivanja na ekran dolazi odmah nakon pokretanja apleta.

Faza zaustavljanja je suprotna fazi pokretanja i nastupa kad korisnik prijeđe u neku drugu aplikaciju. U toj fazi aplet prestaje biti vidljiv na ekranu.

Uništavanje je faza suprotna inicijalizaciji. Faza uništavanja omogućava aplikaciji da “počisti” za sobom. Do te faze dolazi u trenutku kada pretraživač završava s izvršavanjem aplikacije, a ta se faza, poput inicijalizacijske, također događa samo jednom tijekom života apleta. Tijekom faze uništavanja potrebno je počistiti memoriju.

Primjer apleta: Program koji u prozoru pretraživača prikazuje GIF sliku i

svira jednu zvučnu datoteku

import java.awt.*;

import java.applet.*;

public class PrimjerJavaAplet extends Applet {

Image NovaSlika;

public void init ( ) {

resize (400, 400);

NovaSlika = getImage (getCodeBase ( ), “slika.gif”);

}

public void paint (Graphics g) {

g.drawImage (NovaSlika, 0, 0, this);

play (getCodeBase ( ), “zvuk.au”);

}

}

Budući da su apleti napravljeni s namjerom da se izvršavaju unutar Web pretraživača, ne možemo ih pokrenuti koristeći Javin interpreter, kao što smo to učinili sa samostalnim aplikacijama.

Nakon što napišemo i kompiliramo aplet u Javi, trebamo ga uključiti u HTML dokument. Prije nego što ga ugradimo u HTML dokument, moramo sve njegove kompilirane klase (datoteke) poslati na Web poslužitelj u određeni direktorij. Sada u HTML datoteku, pomoću određene oznake, trebamo dodati poziv Java apleta i spremiti tu datoteku u isti direktorij gdje su smještene kompilirane klase apleta.

4. Java i C

Osnovne razlike C-a i Jave su sljedeće:

- Java ne podržava pokazivače.

Pokazivači u C++ su nesigurni i omogućavaju pristup nedefiniranim memorijskim adresama, što dovodi do programskih pogrešaka koje je izuzetno teško pronaći. Umjesto pokazivača, Java posjeduje reference.

- Java nema strukture i skupove.

Strukture i skupovi postali su u Javi nepotrebni jer se mogu realizirati pomoću klasa. Kada deklariramo novu klasu, zapravo smo stvorili novi tip podataka, novu strukturu podataka.

- Java ne podržava preopterećivanje operatora.

Preopterećivanje operatora u C-u može dovesti do programskih kodova koji se mogu dvosmisleno i pogrešno tumačiti. Problemi su posebno očiti kada na razvoju programa radi veća skupina programera, od kojih svaki različito preopterećuje operatore. Jedini operator koji je preopterećen u Javi je operator + , koji omogućava zbrajanje i, istovremeno, spajanje stringova.

- Java ne obavlja automatske pretvorbe svih tipova podataka.

Java će pretvoriti samo one tipove prilikom čije pretvorbe se ne gubi na preciznosti, dok je ostale pretvorbe potrebno naglasiti. U C-u je moguće pretvarati iz bilo čega u bilo što, ali nikada nismo sigurni što ćemo točno dobiti.

- Java koristi klase.

Klase sadrže skupine metoda i varijabli. Zbog toga u Javi ne postoje globalne varijable ili globalne funkcije kao u C-u.

- Java ne podržava nepredznačene brojeve.

Svi brojevi u Javi označeni su predznacima.

- Java ne podržava typedef.

- Java ne podržava goto.

Evo što Java ima, a C nema:

- Višenitnost.

C++ ne podržava višenitno izvršavanje programa.

- Java drugačije pristupa memoriji.

Java ne sadrži operator delete za brisanje podataka iz memorije. Brisanje objekata iz memorije zadaća je Javinog sustava za prikupljanje smeća.

- Naredbe break i continue.

Ove naredbe u Javi podržavaju skokove na labele, čime je izbjegnuta potreba za postojanjem naredbe goto.

- Duljina znakovnog tipa.

Tip char u Javi je dugačak 16 bitova.

Ovdje su navedene samo neke razlike i samo neke prednosti Jave u odnosu na C. Sve drugo ulazilo bi previše u detalje oba programska jezika, a to nije cilj ovoga seminara.

5. Java Virtual Machine

Prilikom kompiliranja, izvorni se kod prevodi u tzv. bajt-kod. Kompilirani bajt-kod može se pokrenuti na svakom računalu za koje postoji Java Virtual Machine (JVM). Interpreter, koji je dio izvršnog sustava, uzima naredbe iz bajt-koda, te ih prevodi u naredbe za konkretno računalo ili operativni sustav. Na taj se način isti bajt-kod može izvršavati na različitim računalima, a upravo JVM ima zadatak da to omogući. Budući da je bajt-kod samo privremeni oblik izvršnog koda, nešto se vremena gubi i na konačno prevođenje u naredbe odredišnog računala.

Što je, zapravo, bajt-kod? Bajt-kod najjednostavnije je zamisliti kao asemblerski jezik za neko izmišljeno računalo. Prilikom definiranja toga izmišljenog računala, potrebno je osmisliti svaki njegov dio, kao kada bismo zaista konstruirali neko stvarno računalo. Treba precizno definirati kako se pojedini dio ponaša i kako se može programirati. Kad kompilator prevodi izvorni kod programa, on iz njega stvara program za tu izmišljenu platformu. To “izmišljeno” računalo naziva se upravo Java Virtual Machine (“prividni stroj”). Ono se nalazi u memoriji našeg računala tijekom izvršavanja programa koji su pisani u Javi, te prevodi naredbe bajt-koda u konkretne naredbe za računalo. Drugi, također veliki dio posla, obavlja interpreter, koji mora “uvjeriti” program pisan u Javi da se izvršava na stvarnom računalu.

Izvršni sustav može se podijeliti u sedam osnovnih dijelova:

- skup registara

- stog

- okružje za izvršavanje programa

- memorijska hrpa

- bazen konstanti

- područje za pohranjivanje metoda

- skup naredbi

Registri u izvršnom sustavu za Javu slični su registrima u pravom računalu. Ipak, postoji jedna značajna razlika. Budući da naredbe Javinog bajt-koda rade isključivo sa stogom, registri se ne koriste za razmjenu podataka u programu, kao što je to slučaj kod “pravih” računala. Stogovi su bolji odabir za tok informacija u programu, jer su većina današnjih računala siromašna registrima.

U izvršnom sustavu postoje četiri registra širine 32 bita:

- pc, programski brojač (program counter)

- opto, pokazivač na vrh operanda, odnosno, pokazivač na vrh stoga koji sadrži operande (operand top)

- frame, referentni okvir (reference frame)

- vars, registar za varijable (variable register).

Javin izvršni sustav koristi stog za slanje parametara metodama, izračunavanje izraza i dobivanje rezultata od njih. Sve naredbe bajt-koda uzimaju podatke sa stoga, nad njima obavljaju svoje operacije i zatim rezultate postavljaju natrag na stog, odakle ih može uzeti neka sljedeća naredba. Poput registara i stog je širine 32 bita.

Okružje za izvršavanje programa je dio stoga. Ono se brine o načinu prosljeđivanja parametara u metode i vraćanju rezultata u glavni program.

Svakom programu koji se izvršava u izvršnom sustavu dodjeljuje se memorijsko područje iz kojeg može alocirati (dobiti) memoriju. To se područje naziva memorijskom hrpom ili memorijskim bazenom. Njegova je standardna veličina 1MB. Unatoč tome što je veličina memorijskog bazena unaprijed određena, on može rasti tijekom izvršavanja programa. No, kako se ne bi dogodilo da memorijska hrpa postane prevelika, Javin izvršni sustav stalno obavlja postupak prikupljanja memorijskog smeća (garbage collection), tijekom kojeg se oslobađa sva memorija koja se više ne koristi.

Svaka klasa iz memorijskog bazena ima svoj bazen konstanti. Budući da se konstantne vrijednosti tijekom izvršavanja programa ne mijenjaju, kompilator može odmah tijekom kompiliranja programa stvoriti posebna memorijska područja namijenjena konstantama, tzv. bazene konstanti. Kompilirana klasa sadrži informacije o tome koliko se konstanti u njoj nalazi i na kojoj memorijskoj adresi počinje njihovo memorijsko područje, bazen.

Javino područje za pohranjivanje metoda slično je područjima u koja drugi programski jezici smještaju kompilirani kod. To područje sadrži bajt-kod koji pripada pojedinoj metodi.

Interpreter proučava svaku naredbu bajt-koda i izvodi radnju koja je označena tim bajt-kodom. Ta se radnja može protegnuti kroz veći broj procesorskih ciklusa, ovisno o procesoru i računalu na kojem se izvršava JVM. Javin interpreter koristi mnoge napredne tehnike za ubrzavanje prevođenja, čime kompenzira vrijeme koje se tijekom izvršavanja programa izgubi na interpretiranju.