Internet Programiranje -JSP

JSP

1. JSP pages typically comprise of:

2. Static HTML/XML components.

3. Special JSP tags

Najčešće, delovi Java koda u okviru JSP stranice se nazivaju „scriptlets.“

JSP stranica se može kreirati pomoću standardnih HTML/XML alata, ali treba naglasiti da je JSP specifikacaija standardni deo Java Servlet API. Zbog ove činjenice u radu sa JSP stranicama iskustvo i znanje o servletima je veom akorisno. Ipak, postoje značajne razlike izmđu ove dve tehnologije. Za razliku od servleta, gde je za programiranje potrebno značajno programersko znanje, JSP tehnologija je mnogo bliža i manje iskusnim programerima, ali i dizajnerima korisničkog interfejsa. Na ovaj način i dizajneru mogu da dobiju značajajniju ulogu u toku razvoja same aplikacije. Još jedna prednost JSP tehnologije je efikasno korišćenje odvojenih nezavisnih programskih segmenata. Time do punog izražaja dolaze sve osobine objektno orijentisanog programiranja. Nezavisni programski segmenti se definišu u okviru komponenata zvanih JavaBeans, a tehnologija koja ih koristi je Enterprise JavaBeans tehnologija.

Da bi se pokretale i JSP stranice i povezivale sa servletima potrebno ih je izvršavati na određenom Web serveru. U okviru ovog kursa koristiće se Jakarta Tomcat Web Server, na kome će se izvršavati svi primeri.

Prednosti JSP tehnologije

Odvojen statički od dinamičkog sadržaja: Kada se klijentski sadržaj generiše u okviru servleta, logika stvaranja dinamičkog sadržaja je sastavni deo koda servleta. Takođe statički deo klijentske strane je “sakrivena” u okviru servleta. Pored otežanog praćenja samog koda, nakon svake, pa i najmanje promene, servlet se mora ponovo kompajlirati. Sve ovo prouzrokuje stvaranje aplikacije čija se logika veom ateško razume, a svaka promena zahteva određeno vreme.

Sa JSP stranicama statički deo se odvaja od dinamičkog korišćenjem specialnih tagova i scriptleta. Kada dizajner strane napravi bilo koju promenu, JSP stranica se automatski rekompajlira i ponovo učita na web server pomoću JSP mašine.

Piši jednom izvršavaj bilo gde: JSP tehnologija donosi ovo pravilo i u interaktivne Web strane. JSP stranice se mogu prenositi sa jedne platforme na drugu, ili promeniti Web server, ponašanje aplikacije će biti potpuno isto.

Dinamički sadržaj se može predstaviti u različitim formatima: Ne postoji pravilo u kom formatu staitički (template) deo JSP stranice mora da bude. Tako, da JSP stranica može koristiti standardni HTML/DHTML kod koji se može izvržavati pomoću browser-a, ili WML kod koji se izvršava na hanheld bežičnim uređajima, dok novije aplikacije koriste XML kod.

Dobijanje Web pristupnog nivoa kod aplikacija n-slojnr arhitekture: Standardna Sunova dokumentacija J2EE TM Blueprints, koja predstavlja glavni vodič za implementaciju složenih Java aplikacija pomoću enterprise Java klasa i JavaBeans, kategorično preporučuje korišćenje JSP stranica u odnosu na servlete za generisanje klijentske strane aplikacije.

Potpuna usklađenost sa servlet tehnologijom: Za svakog servlet programera, potrebno je veoma malo truda i vremena za razumevanje JSP tehnolgije. U stvari, servlet programeri su u velikoj prednosti, jer je su JSP stranice u stvari servelti pisani na velikom nivou apstrakcije. Sve što se može uraditi sa servletima, može i pomoću JSP stranica, ali mnogo jednostavnije!

Arhitektura JSP stranica

Svrha postojanja JSP stranica je definisanje deklarativnog, prezentacijskog metoda za pisanje servleta. Kao što je već navedeno, JSP specifikacija je definisana kao standardna tehnologija na vrhu Servlet API klasa.

Uobičajeno je da JSP stranicaprolazi kroz dve faze: translacionu i fazu odgovra na zahtev. Translaciona faza se izvršava samo jednom, sve dok se u kod stranice ne unesu neke izmene,u kom slučaju se prevođenje ponavlja. Ako u kodu na stranici ne postoji greška, rezultat prevođenja je fajl koji predstavlja klasu implementiranu Servlet interface, kao što je prikazano na slici. Ovu fazu izvršava JSP mašina na web serveru sama, kada primi prvi put zahtev za stranicom. Takođe, JSP stranica se može iskompajlirati u class fajl pre instalacije aplikacije na server čime se izbegava kašnjenje pri prvom pozivu stranice od strane korisnika. Gde se postavlja kod stranice ili iskpmpajlirana klasa zavisi od korišćenog web servera. Kod dobijen od JSP stranice prikazane na gornjoj slici i iskompajliran od strane Tomcat serveraje sledeći:

package jsp;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

import javax.servlet.jsp.tagext.*;

import java.io.PrintWriter;

import java.io.IOException;

import java.io.FileInputStream;

import java.io.ObjectInputStream;

import java.util.Vector;

import org.apache.jasper.runtime.*;

import java.beans.*;

import org.apache.jasper.JasperException;

import java.text.*;

import java.util.*;

public class _0005cjsp_0005cjsptest_0002ejspjsptest_jsp_0

extends HttpJspBase {

static {

}

public _0005cjsp_0005cjsptest_0002ejspjsptest_jsp_0( ) {

}

private static boolean _jspx_inited = false;

public final void _jspx_init() throws JasperException {

}

public void _jspService(HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException {

JspFactory _jspxFactory = null;

PageContext pageContext = null;

HttpSession session = null;

ServletContext application = null;

ServletConfig config = null;

JspWriter out = null;

Object page = this;

String _value = null;

try {

if (_jspx_inited == false) {

_jspx_init();

_jspx_inited = true;

}

_jspxFactory = JspFactory.getDefaultFactory();

response.setContentType(„text/html“);

pageContext = _jspxFactory.getPageContext(this,

request,response, „“, true, 8192, true);

application = pageContext.getServletContext();

config = pageContext.getServletConfig();

session = pageContext.getSession();

out = pageContext.getOut();

// begin

out.write(„\r\n\r\n\r\n“);

// end

// begin [file=“E:\\jsp\\jsptest.jsp“;from=(3,2);to=(5,0)]

Date d = new Date();

String today = DateFormat.getDateInstance().format(d);

// end

// begin

out.write(„\r\nToday is: \r\n „);

// end

// begin [file=“E:\\jsp\\jsptest.jsp“;from=(7,8);to=(7,13)]

out.print(today);

// end

// begin

out.write(“ \r\n\r\n\r\n“);

// end

} catch (Exception ex) {

if (out.getBufferSize() != 0)

out.clear();

pageContext.handlePageException(ex);

} finally {

out.flush();

_jspxFactory.releasePageContext(pageContext);

}

}

}

Dobijena klasa od JSP stranice nasleđuje osnovnu klasu HttpJspBase, čime u stvari vrši implementaciju Servlet interfejsa.Kada se jednom klasa učita u okviru servlet container, _jspService() metod je odgovoran za odgovor na klijeske zahteve. Ovaj metod se ne može preklapati i izvršava se u posebnoj niti u okviru servlet containera. Tok izvršavanja JSP stranice je prikazan na sledećoj slici:

Modeli pristupa JSP stranicama

Rana JSP specifikacija je preporučivala dva metoda pristupa JSP stranicama, koji su nazvani Model 1 i Model 2 arhitekture. Ova dva pristupa su se razlikovala po mestu gde je vršena obrada zahteva. Model 1 arhitektura je sledeća:

Kod ovog modela, Zahtev dobijen od strane web browsera se šalje direktno JSP stranici, koj aje odgovorna za procesiranje zahteva i generisanje odgovora klijentu. Još uvek postoji razdvajanje klijentskog od sreverskog dela aplikacije, jer se svi pristupi podacima odvijaju preko Java Beans. Model 1 arhitektura se može koristiti za jednostavnije aplikacije, dok je za kompleksne implementacije ovaj model nepogodan. Korišćenje ove arhitekture obično dovodi do veoma velike količine scriptleta Java koda u okviru JSP stranice, posebno u slučajevima kada postoji složenije obrada klijetnskih zahteva. Na ovaj način se gubi mogućnost da i dizajneri učestvuju u razvoju logike strane, jer je za ovu vrstu implementacije potrebno veće Java iskustvo. Još jedan nedostatak ovakve arhitekture je da svaka JSP stranica stranica mora individualno da vodi računa o stanju aplikacije.

Arhitektura Modela 2 je sledeća:

Osnovna sintaksa JSP stranica

JSP sintaksu možemo grubo podeliti na direktive, scripting elemente, i standardne akcije.

Direktive

JSP direktive su poruke za JSP mašinu. One ne proizvode nikakav vidljivi izlaz, ali govore mašini šta da radi sa ostatkom JSP stranice. JSP direktive se nalaze u okviru taga. Dve osnovne direktive su page and include. (Postoji još i taglib direktiva, koja se može koristiti za rad sa tag bibliotekama, ali neće biti razmatrana u daljem tekstu.)

Page Direktiva

Uobičajeno je da se ova direktiva nalazi u vrhu svih JSP stranica. Može se navseti proizvoljan broj page direktiva u okviru jedne JSP stranice, ali vrednost u okviru taga mora biti jedinstvena. Nepoznati atributi ili vrednosti dovode do greške pri kompajliranju. Na primer,

dozvoljava korišćenje svih klasa koje postoje u okviru navedenih paketa u okviru scripting elemenata u nastavku stranice, kao i setovanje bafera stranice na 16K.

Include Direktiva

include direktiva daje mogućnost podele sadržahja stranice u manje, lakše razumljive elemente, kao što su uključivanje u svaku stranicu aplikacije standardnih headera ili footer-a. Stranica koja se poziva u okviru ove direktive može biti statička HTML strana ili neki drugi JSP sadržaj. Na primer direktiva:

se može koristiti za prikaz sadržaja fajla copyright.html bilo gde u okviru JSP stranice.

Deklaracije

JSP deklaracije dozvoljavaju definisanje promenljivih na nivou stranice radi snimanja određenih informacija ili definisanja određenih metoda koji su potrebni ostatku JSP stranice. Takođe, na ovaj način se mogu koristiti i JavaBeans komponente. Deklaracija se piše u okviru taga. Uvek se deklaracija promenljivih završava tačka zarezom i njen sadržaj mora biti validna Java naredba. Primer deklaracije promenljive:

Takođe mogu se deklarisati i methodi. Na primer preklapanje osnovnog metoda za inicijalizaciju događaja u okviru života JSP stranice se deklariše na sledeći način:

<%!public void jspInit(){

//some initialization code

}

%>

Izrazi

Kada JSP mašina naiđe na izraz u okviru stranice, izračunava se rezultat izraza, konvertuje u string i direktno prikazuje na izlaznom dokumentu. Obično, izrazi se koriste za prikazivanje vrednosti promenljivih ili vrednosti dobijene nakon izvršavanja pozvane JavaBeans komponente. JSP izrazi se nalaze u okviru taga i ne završavaju se tačka zarezom:

Scriptleti

Java kod u okviru JSP strane ili scriptleti se nalaze u okviru taga. Ovaj Java kod se izvršava pri obradi zahteva od JSP stranice. U okviru scripleta se može pisati bilo koji validan Java kod i količina koda nije limitirana na jednu liniju. Sledeći primer prikazuje string „Zdravo“ pomoću H1, H2, H3, i H4 taga, combinujući korišćenje izraza i scriptleta:

<% for (int i=1; i

<H>Hello</H>

Komentari

Iako se mogu koristiti standardni HTML komentari u okviru JSP stranice, ove komentare klijent može da vidi ako pogleda kod dobijen u okviru browser-a. Ako se to ne želi, mogu se koristiti komentari u okviru taga:

Oblast važenja promenljivih

Predefinisani JSP Objekti

Kao dodatna prednost tehnologije, JSP container dozvoljava korišćenje predefinisanih objekata, koji se mogu koristiti u okviru scriptleta i izraza, bez potrebe da ih autor prvo kreira pre upotrebe. Ovi objekti su:

• request: predstavlja objekat tipa HttpServletRequest. Oblast važenja je u okviru zahteva.

• response: predstavlja objekat tipa HttpServletResponse za zahtev. Ne koristi se često. Oblast važenja je u okviru stranice.

• pageContext: obuhvata osobine u zavisnosti od implementacije u okviru PageContext objekta. Oblast važenja je u okviru stranice.

• application: predstvalja objekat tipa ServletContext. Oblast važenja je u okviru aplikacije.

• out: predstavlja objekat tipa JspWriter koji zapisuje podatke u izlazni stream. Oblast važenja je u okviru stranice..

• config: predstvalja ServletConfig objekat za JSP stranicu. Oblast važenja je u okviru stranice.

• page: sinonim za „this“ operator, to jest za HttpJspPage.objekat. Ne koristi se često. Oblast važenja je u okviru stranice.

• session: objekat tipa HttpSession. Oblast važenja je u okviru sesije.

• exception: objekat tipa Throwable čije izvršavanje rezultuje pozivanjem error stranice koja je definisana u okviru ovog objekta. Oblast važenja je u okviru stranice.

Neki od navedenih metoda su vidljivi samo u okviru _jspService() metoda. Oni nisu vidljivi autoru i ne mogu se koristiti u deklaracijama.

Mogućnosti sihronizacije

Po definiciji service metod JSP stranice implementiran u prevedenu klasu, koji opslužuje zahteve klijenta je višekorisnički (multithreaded). Na ovaj način, odgvoronost je programera da li je pristup deljenim stanjima dobro sihronizovan. Postoji nekoliko načina da se obezbedi da service method bude bezbedan po pitanju sihronizacije. Najlakši način je pomoći sledeće direktive:

Ova direktiva prouzrokuje da se izvrši implementacija SingleThreadModel interface, čiji rezultat je sihronizacija, i više instanci servleta se učitava u memoriju Paralelni zahtevi više klijenata se distribuiraju između ovih instanci. Ovaj metod ne daje najbolje perfomanse. Bolji način je eksplicitni sinhroni pristup deljenim objektima pomoću Java koda u okviru scriptleta:

<%

synchronized (application) {

SharedObject foo = (SharedObject)

application.getAttribute(„sharedObject“);

foo.update(someValue);

application.setAttribute(„sharedObject“,foo);

}

%>

Rukovođenje izuzecima

JSP tehnologija omogućava elegantan mehanizam za handlovanje runtime exception. Korišćenjem atributa errorPage au okviru page direktive, moguće je u slučaju nepredviđene greške usmeriti program na izvršavanje stranice za obradu greške. Na primer,

informiše JSP mašinu d au slučaju bilo kakve neočekivane greške aplikaciju nastavi izvršavanjem JSP stranice errorHandler.jsp. Takođe, neophodno je u okviru errorHandler.jsp tstranice naznačiti da se radi o stranici koja je pozvana, jer se desila greška, pomoću direktive:

Rad sa sesijom

Po definiciji, sve JSP stranice se izvršavaju u okviru HTTP sesije. Objektu HttpSession može se pristupiti iz Java koda implicitnim navođenjem session JSP objekta. Sesije su odlične lokacije za smeštanje objekata kojima je potrebno pristupati iz nekoliko JSP stranica ili servleta. Objekat session se identifikuje preko session ID i zapisan je u okviru browser-a kao cookie. Ako cookies nisu podržani od strane browser-a, tada se session ID može pamtiti pomoću samog URL, ali je ova mogućnost podržana samo kod nekoliko web servera:

<%

Foo foo = new Foo();

session.putValue(„foo“,foo);

%>

omogućava pristup Foo instanci preko svih JSP stranica i servleta koji pripadaju istoj sesiji. Instanci ovog objekta se može pristupiti sa druge JSP stranice preko sledećeg koda:

<%

Foo myFoo = (Foo) session.getValue(„foo“);

%>

Poziv session.getValue() vraća referencu na osnovni Object tip. Zato je veoma važno navesti kog tipa je promenljiva koja je pročitana, pre njenogkorišćenja. Moguće je definisati da određena JSP stranica ne pripada sesiji pomoću određenog atributa u okviru page direktive:

Ne postoji limitiran broj koliko se objekata može zapamtiti u okviru sesije. Treba napomenuti da smeštanje velikih objekata u sesiju može bitno da degradira perfomanse aplikacije. Po definiciji većina servera setuje vreme objekta sesije na 30 minuta, ali se može jednostavno resetovati i menjati pozivom metoda invoking setMaxInvalidationInterval(int secs) nad objektom sesije. Naredna slika opisuje način rukovođenja sesijom:

JSP mašina održava reference na objekte smeštene u sesiji onoliko dugo koliko je sesija validna. Ako sesija postaje nevalidna ili istekne vreme sesije, objecti sesije se označavaju za garbage collection.

Hidden promenljive

Organizacija Web Aplikacije

Jedna od mogućnosti je distribucija Web aplikacije u obliku fajla Web ARchive, ili WAR fajla, koji predstvalja standardni format za većinu servera.

Prvi i osnovni direktorijum se naziva document root aplikacije. Tu se smeštaju HTML fajlovi i JSP stranice, to jest klijentski deo aplikacije.Kada se aplikacija instalira na sistem definiše se putanja do aplikacije. Na primer ako je definisana putanja /catalog, tada pozivni URI glasi /catalog/index.html i izvršavaće se index.html sa document roota aplikacije.

Standardni Direktorijumi

• *.html, *.jsp, itd. – HTML i JSP stranice, zajedno sa ostalim fajlovima koji se koriste na kloijetskoj strani (kao što su JavaScript i stylesheet fajlovi) se smeštaju u osnovni direktorijum. Kod većih aplikacija može se napraviti poddirektorijumi i ova hijerarhija.

• WEB-INF/web.xml – Web Application Deployment Descriptor Ovo je XML fajl koji opisuje servlete i druge komponente koji čine aplikaciju, zajedno sa bilo kojim inicijalizacionim parametrima i različitim oblicima zaštite.

• WEB-INF/classes/ – U ovaj direktorijum se smeštaju sve Java klase koje se koriste u aplikaciji, uključujući i sevlet i ne-servlet klase.

• WEB-INF/lib/ – U ovaj direktorijum se smeštaju svi JAR fajlovi potrebni za izvršavanje aplikacije (kao što su na primer JDBC dajveri).

JDBC

JDBC je JAVA API za baze podataka bazirane na SQL jeziku. JDBC je predstavljen u obliku na nivou poziva SQL interface za Javu. Znači, pomoću klasa iz ovog paketa se mogu izvršavati SQL naredbe i manipulisati sa rezultatima dobijenim na osnovu ovih naredbi.

JDBC API sadrži niz abstraktnih Java interface koji dozvoljavaju programeru da ostvari konekciju sa određenom bazom podataka, izvrši SQL naredbe i obradi dobijene rezultate.

Najvažniji interface u okviru ovog paketa su:

– java.sql.DriverManager sprovodi učitavanje driver-a baze podataka i omogućava podršku za kreiranje nove konekcije

– java.sql.Connection predstavlja konekciju sa određenom bazom podataka

– java.sql.Statement izvrašava se u obliku container-a za izvršavanje SQL naredbi u okviru uspostavljene konekcije

– java.sql.ResultSet kontroliše pristup rezultatima dobijenim izvršavanjem određene SQL naredbe

java.sql.Statement interface ima dva važna podtipa:

– java.sql.PreparedStatement za izvršavanje pre-kompajlirane SQL neredbe i

– java.sql.CallableStatement za izvršavanje poziva stored procedura koje postoje u okviru baze podataka.

JDBC URL ima sledeću strukturu: jdbc:: gde je subprotocol ime odrđene vrste mehanizma pristupa bazi podataka koji može biti podržan od jednog ili više drajvera. Sadržaj i sintaksa dela subname zavisi od subprotocola.

JDBC management nivo mora da zna koji drajver je raspoloživ i koji drajver se koristi..

Primer inicijalizacije drajvera baze podataka:

Class.forName(„sun.jdbc.odbc.JdbcOdbcDriver“);

Class.forName(„org.gjt.mm.mysql.Driver”);

Example: Execute Query

import java.sql.*;

public class JDBCDemoCreateTable {

public static void main(String[] args) {

// 1. step loading the driver

try {

Class.forName(„sun.jdbc.odbc.JdbcOdbcDriver“);

// 2. step making the connection

String url = „jdbc:odbc:BootCamp“ ;

String myLogin = „mika“ ; // the name you use to log in to the DBMS

String myPassword = „mika“ ; // your password for the DBMS

try {

Connection con = DriverManager.getConnection( url, myLogin, myPassword );

String createTableCoffees = „CREATE TABLE COFFEES “ +

„(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, “ +

„SALES INTEGER, TOTAL INTEGER)“;

// 3. step creating JDBC sStatement. A Statement object is what sends your SQL

// statement to the DBMS. You simply create a Statement object and then execute

// it, supplying the appropriate execute method with the SQL statement you want

// to send. For a SELECT statement, the method to use is executeQuery . For

// statements that create or modify tables, the method to use is executeUpdate

Statement stmt = con.createStatement();

stmt.executeUpdate(createTableCoffees);

} catch ( SQLException e ) { System.err.println( e ); }

}catch ( ClassNotFoundException e) { System.out.println(„Error : “ + e ); }

}

}—-

import java.sql.*;

public class JDBCDemoUpdateTable {

public static void main(String[] args) {

try {

Class.forName(„sun.jdbc.odbc.JdbcOdbcDriver“);

try {

Connection con = DriverManager.getConnection( „jdbc:odbc:BootCamp“, „mika“, „mika“ );

Statement stmt = con.createStatement();

String updateTableCoffees = „INSERT INTO COFFEES VALUES (‘Colombian’, 101, 7.99, 0, 0)“ ;

stmt.executeUpdate( updateTableCoffees );

updateTableCoffees = „INSERT INTO COFFEES VALUES (‘French_Roast’, 49, 8.99, 0, 0)“ ;

stmt.executeUpdate( updateTableCoffees );

updateTableCoffees = „INSERT INTO COFFEES VALUES (‘Espresso’, 150, 9.99, 0, 0)“ ;

stmt.executeUpdate( updateTableCoffees );

updateTableCoffees = „INSERT INTO COFFEES VALUES (‘Colombian_Decaf’, 101, 8.99, 0, 0)“ ;

stmt.executeUpdate( updateTableCoffees );

updateTableCoffees = „INSERT INTO COFFEES VALUES (‘French_Roast_Decaf’, 49, 9.99, 0, 0)“ ;

stmt.executeUpdate( updateTableCoffees );

} catch ( SQLException e ) { System.err.println( e ); }

}catch ( ClassNotFoundException e) { System.out.println(„Error : “ + e ); }

}

}—

import java.sql.*;

public class JDBCDemoSelectTable {

public static void main(String[] args) {

try {

Class.forName(„sun.jdbc.odbc.JdbcOdbcDriver“);

try {

Connection con = DriverManager.getConnection( „jdbc:odbc:BootCamp“, „mika“, „mika“ );

Statement stmt = con.createStatement();

String queryTableCoffees = „SELECT COF_NAME, SUP_ID, PRICE, SALES, TOTAL FROM COFFEES“ ;

// JDBC returns results in a ResultSet object, so we need to declare an instance of the

// class ResultSet to hold our results. The following code demonstrates declaring the

// ResultSet object rs and assigning the results of our earlier query to it:

ResultSet rs = stmt.executeQuery( queryTableCoffees );

while (rs.next()) {

String coffeName = rs.getString(„COF_NAME“);

int supplierId = rs.getInt(„SUP_ID“);

float price = rs.getFloat(„PRICE“);

int sales = rs.getInt( 4 );

int total = rs.getInt( 5 );

// JDBC allows you to use either the column name or the column number as the argument to a getXXX method

System.out.println( coffeName + “ “ + supplierId + “ “ + price + “ “ +

sales + “ “ + total );

}

} catch ( SQLException e ) { System.err.println( e ); }

} catch ( ClassNotFoundException e) { System.out.println(„Error : “ + e ); }

}

}—

Example: Using parameter Query

/**

*

* If you want to execute a Statement object many times, it will normally reduce

* execution time to use a PreparedStatement object instead.

*

*/

import java.sql.*;

public class JDBCDemoPreparedStatement {

public static void main(String[] args) {

try {

Class.forName(„sun.jdbc.odbc.JdbcOdbcDriver“);

try {

Connection con = DriverManager.getConnection( „jdbc:odbc:BootCamp“, „mika“, „mika“ );

PreparedStatement updateSalesPrepared = con.prepareStatement( „UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?“);

int [] salesForWeek = {175, 150, 60, 155, 90};

String [] coffees = {„Colombian“, „French_Roast“, „Espresso“,

„Colombian_Decaf“, „French_Roast_Decaf“};

int len = coffees.length;

for(int i = 0; i < len; i++) {

updateSalesPrepared.setInt(1, salesForWeek[i]); // setting up first parameter

updateSalesPrepared.setString(2, coffees[i]); // setting up second parameter

updateSalesPrepared.executeUpdate(); // executing update

}

Statement stmt = con.createStatement();

String queryTableCoffees = „SELECT COF_NAME, SALES FROM COFFEES“ ;

ResultSet rs = stmt.executeQuery( queryTableCoffees );

while (rs.next()) {

String coffeName = rs.getString(„COF_NAME“);

int sales = rs.getInt(2);

System.out.println( coffeName + “ “ + sales );

}

} catch ( SQLException e ) { System.err.println( e ); }

} catch ( ClassNotFoundException e) { System.out.println(„Error : “ + e ); }

}

}

Example: Using CallableStatement

import java.sql.*;

public class JDBCDemoCallableStatement {

public static void main(String[] args) {

try {

Class.forName(„sun.jdbc.odbc.JdbcOdbcDriver“);

String url = „jdbc:odbc:BootCamp“ ;

String myLogin = „mika“ ; // the name you use to log in to the DBMS

String myPassword = „mika“ ; // your password for the DBMS

try {

Connection con = DriverManager.getConnection( url, myLogin, myPassword );

// A stored procedure is a group of SQL statements that form a logical unit and perform a particular task

String createProcedure = „create procedure SHOW_SUPPLIERS “ +

„as “ +

„select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME “ +

„from SUPPLIERS, COFFEES “ +

„where SUPPLIERS.SUP_ID = COFFEES.SUP_ID “ +

„order by SUP_NAME“;

Statement stmt = con.createStatement();

stmt.executeUpdate(createProcedure);

// Calling a Stored Procedure from JDBC

CallableStatement cs = con.prepareCall(„{call SHOW_SUPPLIERS}“);

ResultSet rs = cs.executeQuery();

while (rs.next()) {

String supName = rs.getString(„SUP_NAME“);

String coffyName = rs.getString(„COF_NAME“);

System.out.println( supName + “ “ + coffyName );

}

}catch ( SQLException e ) { System.err.println( e ); }

} catch ( ClassNotFoundException e) { System.out.println(„Error : “ + e ); }

}

}

Mapping SQL data types into Java and Use of ResultSet.getXXX Methods to Retrieve JDBC Types

SQL type TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE DECIMAL NUMERIC BIT CHAR VARCHAR LONGVARCHAR BINARY VARBINARY LONGVARBINARY DATE TIME TIMESTAMP

Java Type String String String java.math.BigDecimal java.math.BigDecimal boolean byte short int long float double double byte[] byte[] byte[] java.sql.Date java.sql.Time java.sql.Timestamp

getByte X x x x x x x x x x x x x

getShort x X x x x x x x x x x x x

getInt x x X x x x x x x x x x x

getLong x x x X x x x x x x x x x

getFloat x x x x X x x x x x x x x

getDouble x x x x x X X x x x x x x

getBigDecimal x x x x x x x X X x x x x

getBoolean x x x x x x x x x X x x x

getString x x x x x x x x x x X X x x x x x x x

getBytes X X x

getDate x x x X x

getTime x x x X x

getTimestamp x x x x x X

getAsciiStream x x X x x x

getUnicodeStream x x X x x x

getBinaryStream x x X

getObject x x x x x x x x x x x x x x x x x x x

An „x“ indicates that the getXXX method may legally be used to retrieve the given JDBC type.

An “ X “ indicates that the getXXX method is recommended for retrieving the given JDBC type.

Relationships between the interface

Advertisements

prvi java aplet

Prvi JAVA aplet

Applet ZdravoAplet

Jedan od razloga popularnosti Jave je mogućnost pisanja interaktivnih apleta na Web-u. Naredni aplet nije baš interaktivan, jer je primer jednostavnog apleta koji ispisuje tekst poruke u HTML dokument:

import java.applet.Applet;

import java.awt.Graphics

public class ZdravoAplet extends Applet {

public void paint(Graphics g) {

g.drawString(„Zdravo, svete!“, 5, 50);}

}

Aplet ZdravoAplet jeste malo kompleksniji u odnosu na aplikaciju ZdravoSvete. Zatim, potrebno je i više posla pri pokretanju.

Kao i pri izradi aplikacije urade se dva koraka: unos izvornog koda u editor i čuvanje u datoteci ZdravoSvete.java i kompilacija.

Rezultat je klasa ZdravoAplet.class. Za potrebe njenog pokretanja kreira se HTML dokument koji će sadržati aplet, npr.datoteka (ZdravoAplet.html)

Zdravo aplet

Jednostavnosti radi, neka se datoteka datoteka ZdravoAplet.html i datoteka datoteka ZdravoAplet.class nalaze u istom direktorijumu.

HTML datoteka se može pregledati pomoću Java enabled browsera kao što je Internet Explorer, Netscape ili Applet viewer koji se nalazi u JDK paketu.

Vidi se string Zdravo, svete ! unutar pravougaonika veličine 400×400 pixel-a.

Ako je kompilacija prošla bez greške, a ne vidi se string Zdravo, svete !, onda:

1. proveriti da li klasa je u istom direktoriju kao i HTML datoteka

2. proveriti da li koristete verziju navigatora koja podržava Javu.

3. ako ni appletviewer ne vidi aplet, proveriti aplet, pa potom kompatiblnost navigator-a

Razvojni put apleta

Applet je mala aplikacija koja je zamišljena da se ne izvršava samostalno, nego unutar druge aplikacije, tnpr. unutar web browsera. Klasa java.applet.Applet osigurava standardnu sumedju izmedju apleta i njihove okoline. Evo što se sve naziva appletom:

mala aplikacija

sigurni program koji se izvršava unutar web browsera

podklasa klase java.applet.Applet

instanca podklase od java.applet.Applet

Ovo je hijerarhija njenih nadklasa:

java.lang.Object

|

+—java.awt.Component

|

+—java.awt.Container

|

+—java.awt.Panel

|

+—java.applet.Applet

HTML oznaka

Appleti se u HTML kod ugrađuju pomoću oznake i . Oznaka se ponaša na Web strani poput oznake . Kompajlirana klasa koja sadrži kod apleta kod referencira se pomocu atributa CODE, a lokacija se zadaje relativno u odnosu na izvorni HTML dokument.

Na primer, ako je URL HTML dokumenta http://www.nesto.com/java/index.html, i ako se u HTML kodu applet referiše sa CODE=“Nesto.class“, onda URL datoteke Nesto.class je http://www.nesto.com/java/Nesto.class.

Ali, ako se aplet ne nalazi u istom direktoriju kao i HTML dokument, ne može se u atributu jednostavno navesti njegov URL, nego se koristi još i atribut CODEBASE za preciziranje URL fragmenta koji pokazuje put do apleta. Na primer, da je HTML stranica sa apletom ZdravoAplet bila napisana kao

<APPLET CODE="ZdravoAplet.class" CODEBASE="JavaKlase"

WIDTH=200 HEIGHT=200>

onda bi browser pokušao tražiti klasu ZdravoAplet.class u poddirektorijumu JavaKlase onog direktorijuma u kom se nalazi HTML dokument.

Slično, ako postoji fragment

onda će browser pokušati naći klasu na adresi http://www.nesto.com/java/JavaKlase/ZdravoAplet.class bez obzira gde se nalazi HTML dokument.

Ukratko, browser pokušava rekonstruisati URL po formuli (CODEBASE+ „/“ + CODE). Jednom kad je URL formiran, važe sva pravila o relativnim i apsolutnim URL-ovima.

Ekstenzija .class se može izostaviti u atributu CODE i navesti samo ime klase. Na primer

<APPLET CODE="ZdravoAplet"

CODEBASE=“http://www.nesto.com/java/JavaKlase&#8220;

WIDTH=200 HEIGHT=200>

Ako applet nije u default paketu, potrebno je pisati puno ime paketa. Na primer <APPLET CODE="program.myApplets.ZdravoAplet"

CODEBASE=“http://www.nesto.com/java/JavaKlase&#8220; WIDTH=200 HEIGHT=200>

U ovom primeru browser traži klasu na adresi http://www.nesto.com/java/JavaKlase/program/myApplets/ZdravoAplet.class, te struktura direktorijuma na serveru mora biti u skladu s hijerarhijom paketa.

Atributi HEIGHT i WIDTH imaju svojstva slična istoimenim atributima oznake IMG, tj. određuju dimenzije pravougaonika koji rezerviše browser za prikaz appleta. Veličine se zadaju u pikselima i nisu opcione.

Odabir pozicije na stranici

Oznaka ima nekoliko atributa za definisanje pozicije apleta na stranici.

Atribut ALIGN određuje kako je pravougaonik apleta pozicioniran na Web strani u odnosu na druge elemente. Dozvoljene vrednosti ovog atributa su LEFT, RIGHT, TOP, TEXTTOP, MIDDLE, ABSMIDDLE, BASELINE, BOTTOM i ABSBOTTOM. Prisustvo atributa je opcionalno.

U atributima HSPACE i VSPACE moguće je odrediti količinu praznog prostora (u pikselima) između apleta i okružujućeg teksta. I ovi su atributi opcionalni.

Atributi ALIGN, HSPACE, i VSPACE identični su onima koji se koriste u oznaci .

Alternativni tekst

Oznaka ima i atribut ALT. Browser ga koristi ukoliko nije moguće pokrenuti aplet. Na primer, ako u browseru je isključena opcija za dozvolu pokretanja Java appleta, prikazuje se tekst poruke naveden kao vrednost atributa ALT. Atribut ALT je opcionalan.

<applet code="ZdravoAplet.class" CODEBASE="http://www.nesto.com/java/JavaKlase&quot; width=200 height=200 ALIGN=RIGHT HSPACE=5 VSPACE=10

ALT=“Zdravo svima!“>

Ovaj atribut nije upotrebljiv kod starijih browsera koji ne poznaju ni oznaku . Oni umesto toga prikazuju isti tekst koji se nalazi između oznake i njenog zatvarajućeg oblika . S druge strane, browseri Java enabled browseri će taj tekst ignoriati. Na primer, naredni fragment HTML koda ispisuje string Zdravo,svete i Java enabled i non-Java enabled browserima:

<applet code="ZdravoAplet.class" width=200 height=200 ALIGN=RIGHT HSPACE=5 VSPACE=10

ALT=“Zdravo svete!“>Zdravo svete!



Imenovanje appleta

Apletu se unutar web stranice može dati naziv koji se koristi pri komunikaciji sa drugim apletima. U tu svrhu koristi se atribut NAME. Na primer,

<applet code="ZdravoAplet.class" Name=PrviAplet

width=200 height=200 ALIGN=RIGHT HSPACE=5 VSPACE=10 ALT=“Zdravo!“>Zdravo!

JAR arhive

Sve slike, zvučni zapisi i klase koje su neophodne u toku izvršavanja apleta mogu se spakovati u JAR arhivu i učitati se odjednom. Time se smanjuje broj konekcija koje browser ostvariti pri zasebnom učitavanju da bi nabavio neophodne stavke izvršenja. Ako se aplet klasa nalazi u takvoj arhivi, onda se oznaci dodaje još i atribut . Na primer:


Zdravo, svete!



U ovom primeru klasa apleta je i dalje ZdravoApplet. Međutim, browser će odgovarajuću datoteku potražiti u arhivi ZdravoSvete.jar, a ne u posebnoj datoteci ZdravoAplet.class.

Arhiva može biti kreirana na jedan od uobičajenih načina u konzoli, na primer:

% jar cf ZdravoSvete.jar ZdravoAplet.class

added manifest

adding: ZdravoAplet.class(in = 384) (out= 271)(deflated 29%)

%

Ako se želi pogledati koji sadržaj postoji u arhivi, onda:

% jar tf ZdravoSvete.jar

META-INF/

META-INF/MANIFEST.MF

ZdravoAplet.class

%

HTML oznaka

HTML 4.0 uvodi umesto oznake novu oznaku . Umesto atributa CODE uvodi se atribut CLASSID. Na primer:

Oznaka je uvedena u nastavku o plug-in i JavaScript-u i oznaka omogućuje uključivanje ActiveX kontrola i drugih aktivnih elemenata, ali za Javu to nije od značaja. Oznaka je podržana od strane najnovijih verzija browsera i smatra se da će oznaka biti aktuelna još dosta dugo.

Mogu postojati i obe oznake, jedna unutar druge, na primer:

<OBJECT CLASSID="ZdravoAplet.class" WIDTH=200 HEIGHT=200

>

<APPLET CODE="ZdravoAplet.class"

WIDTH=200 HEIGHT=200>

Browseri koji podržavaju oznaku ignorišu sadržaj između nje i njenog zatvarajućeg oblika, dok ga ostali browser-i prikazuju. Oznaka PARAM može da stoji uz obe oznake o čemu će biti više reči u narednom nastavku.

Metode init(), start(), stop() i destroy()

Svi apleti imaju sledeća četiri metoda:

public void init();

public void start();

public void stop();

public void destroy();

Imaju ih jer ih ima njihova nadklasa, java.applet.Applet (pored ostalih, naravno). U nadklasi su one samo deklarisane i ne čine ništa, npr.

public void init() {}

Podklase mogu (ali i ne moraju) prekriti ove metode kako bi ispunile određene zadatke u određeno vreme. Na primer, metod init() je dobar izbor za učitavanje parametara iz oznake , jer ona se poziva u trenutku kad aplet počinje izvršavanje. S obzirom da sui da su deklarisani u nadklasi, Web browser će pozvati te metode kad su mu potrebne, čak ni ne znajući jesu li implementirane u appletu ili u nadklasi. To je primer polimorfizma.

Metod start() se poziva bar jednom u appletovom životnom ciklusu, onda kad se aplet učita i svaki put kada se strana sa tim apletom ponovo učita (restart, reload). Mnogi apleti nemaju eksplicitni start()metod nego ga nasleđuju iz nadklase. Najčešće se koristi za pokretanje niti koje će applet trebati tokom izvršavanja.

Metod stop() se poziva bar jednom, kad browser napusti stranicu koja sadrži aplet. Kad se na nju opet vrati, poziva se metod start(). Koristi se za zaustavljanje zaustavljanje threadova koje aplet koristi. Kad je se učita neka nova stranica i tad se aplet zaustavlja.

Metod destroy() se poziva tačno jednom u životnom ciklusu apleta, pre nego browser otpusti aplet. Koristi se uglavnom za finalno čišćenje.

U JDK appletvieweru, izbor opcije Restart poziva stop() i onda start().

Opcija Reload poziva redom stop(), destroy() i init(). (Normalno bi byte kodovi trebali biti ponovno učitani zajedno s HTML dokumentom, no u Netscapeu postoji problem s tim.)

Appletovi metodi start() i stop() nemaju veze sa istoimenim metodama iz klase java.lang.Thread.

Vaš vlastiti kod poziva povremeno metode start() i stop(). S druge strane, pozivanje metoda init() i destroy() nije dobra ideja. Browser (ili druga okolina) je taj koji poziva ove metode.

java appleti

Postoje dve kategorije JAVA programa:
1. Java apleti (applets)
2. Java aplikacije

Java apleti su programi ugrađeni u HTML dokumente koji se izvršavaju u lokalnom Web navigatoru. Za njihovo izvršavanje neophodno je da navigator poseduje ugrađene JAVA sposobnosti, ali se mogu pogledati i pomoću alata zvanog appletviewer koji dolazi u okviru JDK .
Java aplikacije ne zahtevaju navigator da bi se pokrenuli, a neki Java program može biti aplet ili aplikacija ili jedno i drugo u zavisnosti od funkcionalnosti koja je ugrađena u program.

Primer 1: Java aplikacija za primer ispisa niske Zdravo, svete na standardni izlaz.

class ZdravoSvete {
public static void main (String args[])
{
System.out.println(„Zdravo, svete“);
}
}

Postoje dva suštinska dela ovog programa:
definicija: kompletan program je zatvoren u definiciju klase koja se ovde zove ZdravoSvete
telo programa: kao i u C/C++ funkcija main( ) je prva funkcija koja se izvršava po startovanju programa.
1. Nakon što je program unet u editor (ma koji editor), izvorna datoteka se čuva sa ekstenzjom .java
2. Praksa je da se izvornom kodu daje ime klase koja je u njemu definisana, dakle datoteku nazovite ZdravoSvete.java
3. Kompajlirajte datoteku javac kompajlerom, tj. u komandnoj liniji otkucajte
javac ZdravoSvete.java
4. Kompajler će kao izlaz dati fajl istog imena sa ekstenzijom .class (ekstenzija izvršnih Java programa)
5. Pokrenite program java interpreterom, tj. u komandnoj liniji otkucajte
java ZdravoSvete

Dakle, postoje tri suštinska koraka u stvaranju/izvršavanju programa:
1. pisanje kôda
2. kompilacija izvornog kôda
3. pokretanje kompajliranog kôda

Pod UNIXom kompilacija i izvršavanje izgleda ovako:

javac ZdravoSvete.java
java ZdravoSvete
Zdravo, svete

Ako se na računaru Java kompajler (javac), Java interpreter (java) i ostali alati nalaze u direktoriju /nesto/java/bin, onda dodati putanju direktorijuma u $PATH promenljivu:
% export PATH=$PATH:/nesto/java/bin

Pod Windows-om mora se koristiti DOS-shell pri upotrebi JDK:

C:> javac ZdravoSvete.java
C:> java ZdravoSvete
Zdravo, svete
C:>

Pri tom se podesi vrednost promenljive PATH tako da sadrži adekvatni direktorijum gde je instaliran jdk, npr . . .;c:\nesto\jdk1.4.0_02\bin\; . . . (definisana u odgovarajućoj liniji datoteke autoexec.bat ili se podesi vrednost putem
Start => Settings => System=> Environment Variables => PATH )

/******Primetite upotrebu .java ekstenzije kod kompajliranja, ali ne i .class ekstenzije kod izvršavanja!!!***********/

Preporuke pri izradi Java programa

1. Fajlovi koji sadrže izvorni kod nazvati po definisanim klasama unutar fajla, jer kompajler će kao izlaz dati fajl sa ekstenzijom .class i imenom klase koja je u fajlu definisana, te nije zgodno da nazivi datoteka sa izvornim i izvršivim kodom budu različiti.
2. Zgodno je definisati jednu klasu u jednom fajlu, jer kompajler svaku prevedenu klasu smešta u poseban .class fajl, te je moguće od jedne izvorne datoteke dobiti više .class fajlova što može biti neudobno za celokupnu organizaciju na disku.
3. Java interpreter java je osetljiv na veličinu slova (case sensirive) u nazivu datoteka.
4. Pri interpretiranju ne kucati ekstenziju .class iza naziva programa, jer zbog interne koncepcije jezika tačka može biti protumačena kao deo puta do izvršive verzije.

Ispis na standardni izlaz

U prethodnoj aplikaciji za ispis poruke Zdravo, svete na standardni izlaz je upotrebljen metod println, tj. System.out.println(„Zdravo, svete“);

Za ispis linije koristi se metod println(…) iz klase PrintStream. U našem prvom Java programu
System.out.println() ispisuje sadržaj toka standardnog izlaza System.out
klase System, u ovom slučaju tekst poruke iza kog sledi separator linije. Zavisno od platforme to moze biti:
carriage return(ASCII 13, \r) i linefeed (ASCII 10, \n) na DOS/Windows
linefeed na UNIX
carriage return na Mac-u

System.err.println(…) ispisuje sadržaj na standardni tok za poruke o grešci System.err.

Moguće je konkatenirati niske koje su argumenti metode println() pomoću znaka +, npr.
System.out.println(„Ucitano je “ + args.length + „argumenata s komandne linije“);
gde args.length predstavlja broj argumenata komandne linije.

Ako se koristi print(…) umesto println(), onda nema znaka za prelaz u novi red nakon ispisa, npr.
System.out.print(„Ucitano je „);
System.out.print(args.length);
System.out.print(“ argumenata s komandne linije“);
System.out.println();

System.out.println() prekida liniju i pokreće ispis, te se ništa neće ispisati na ekranu
dok god se ne pojavi znak prelaza u novi red.

Klasa ZdravoSvete

Program u Java-i predstavlja klasu. Svaka klasa ima ime koje, po konvenciji, počinje velikim slovom, npr.
class ZdravoSvete
Prva linija aplikacije našeg primer glasi
public static void main (String args[])
Aplikacije u Java-i iamju f-ju main od koje i počinje izvršavanje.
public čini aplikaciju javnom (dostupnom spolja), tj. iz konzole.
Java program se sastoji iz niza naredbi unutar bloka omeđenog vitičastim zagradama. U našem primeru to je metod println.

main (String args[])
pod imenom args definiše niz stringova koji su parametri komandne linije. Niz args[] sakuplja sav tekst komandne linije otkucan iza imena programa i kad se pokrene program, onda args[0] sadrži prvi string komandne linije, …, jer ime klase nije uključeno u listu argumenata.
Argumenti komandne linije se, dakle, mogu preneti u program i to kao niz stringova args. Početni indeks svakog niz je nula kao u C/C++. Npr, ako tekst komandne linije glasi
java stampaj Zdravo Pero
onda args[0] je string „Zdravo“, args[1] je string „Pero“, dok args.length je 2.

Svi argumenti komandne linije prenose se kao stringovi, nikad kao brojevi. Kasnije će prikazati konverzija stringova u brojeve.

U Java-i postoje dve klase za rad sa tekstom i njegovo pohranjivanje: String, StringBuffer.

Razvijni put aplikacije

Obrada izuzetaka

Obrada izuzetaka

Izuzeci su mehanizam za kontrolu toka programa koji se koristi za obradu grešaka nastalih u toku izvršavanja programa. Segment programskog koda za koji smatramo da može da izazove izuzetak možemo da smestimo u tzv. try/catch blok, kao u sledećem primeru:

try {

// kod koji može da izazove izuzetak

} catch (Exception ex) {

System.out.println(„Desio se izuzetak: “ + ex);

}

Izuzetak može biti, na primer, deljenje nulom, pristup elementu niza koji je izvan granice niza, itd. Ukoliko se prilikom izvršavanja koda koji se nalazi u try bloku desi izuzetak, tok izvršavanja programa se automatski prebacuje na početak catch bloka. Nakon izvršavanja koda u catch bloku, program dalje nastavlja rad.

U okviru catch bloka, informacije o samom izuzetku koji se dogodio su dostupne preko objekta klase Exception ili neke njene naslednice. U primeru je to objekat ex.

Različite vrste izuzetaka su predstavljene različitim exception klasama, na primer: svi izuzeci prilikom izvršavanja aritmetičkih operacija (deljenje nulom, overflow itd.) su predstavljeni klasom Arithmetic Exception; pristup elementu čiji je indeks izvan granice niza je predstavljen klasom ArraylndexOutOfBounds-Exception itd. Klasa Exception je zajednički predak svim exception klasama.

Jedan try blok može imati više sebi pridruženih catch blokova, kao u sledećem primeru:

try {

// kod koji može da izazove izuzetak

}

catch (ArithmeticException ex) {

System.out.println(„Deljenje nulom“);

}

catch (ArrayIndexOutOfBoundsException ex) {

System.out.println(„Pristup van granica niza“);

}

catch (Exception ex) {

System.out.println(„Svi ostali izuzeci“);

}

finally {

// kod koji se izvršava u svakom slučaju

}

Kada se dogodi izuzetak, niz catch blokova se sekvencijalno obilazi i ulazi se u onaj catch blok čija klasa odgovara izuzetku koji se dogodio. Reč odgovara u ovom slučaju znači: u pitanju je klasa kojoj exception objekat pripada ili njen predak. Kada poslednji catch blok hvata izuzetak klase Exception, to znači da će svi izuzeci biti obrađeni, jer je klasa Exception zajednički roditelj. Blok finally se ne mora navesti. On sadrži blok koda koji će se izvršiti u svakom slučaju, desio se izuzetak ili ne.

Kao što postoje odgovarajuće klase koje opisuju različite vrste izuzetaka, moguće je definisati i nove vrste izuzetaka definicijom odgovarajuće klase. Na primer, možemo da definišemo novu vrstu izuzetka predstavljenog klasom MojException, koja je data u primeru:

public class MojException extends Exception {

public MojException() {

super();

}

public MojException (String msg) {

super(msg);

}

}

Klasa MojException ima dva konstruktora koji pozivaju odgovarajuće konstruktore roditeljske klase Exception. Pisanje ovakvih konstruktora nije obavezno, ali je obavezno naslediti klasu Exception (ili nekog njenog potomka).

Dosad ste samo hvatali izuzetke koje je bacao Javin izvršni sistem. Međutim, vaš program može i izričito da baci određeni izuzetak pomoću naredbe throw. Ovakav korisnički izuzetak može biti izazvan samo programski, pomoću ključne reči throw, kao u sledećem primeru:

If (errorCheck())

throw new MojException („Houston, we have a problem.“);

Programski kôd koji sadrži ovakvu throw naredbu mora biti smešten unutar try bloka koji hvata izuzetak MojException – na to će nas naterati kompajler. Dakle, ovo bi moglo da izgleda na sledeći način:

try {

if(errorCheck())

throw new MojException(„Houston, we have a problem.“);

} catch (MojException ex) {

System. out. println( „Exception: “ + ex);

}

}

Drugi način da obradimo nastanak ovakvog izuzetka je da metodu u kojoj se nalazi throw naredba označimo kao metodu u kojoj može da nastane izuzetak date vrste. Na primer:

public void metoda() throws MojException {

if (errorCheck())

throw new MojException(„Houston, we have a problem.“);

}

Sada poziv ovakve metode mora biti u odgovarajućem try bloku ili metoda koja sadrži ovaj poziv mora isto biti označena da može da izazove izuzetak. Dakle:

public void ml() {

try {

metoda ();

} catch (MojException ex) {

System. out. println („Exception: “ + ex);

}

}

ili

public void ml() throws MojException {

metoda();

}

Pogledajmo sledeći primer koji pravi sopstvenu klasu za obradu izuzetka:

class KlasaIzuzetak extends Exception {

private int iz;

KlasaIzuzetak(int a) {

iz = a;

}

public String toString() {

return „Klasa izuzetak[“ + iz + „]“;

}

}

class GlavniSopstvena{

static void Obradi(int a) throws KlasaIzuzetak {

System.out.println(„Pozvana obrada(“ + a + „)“);

if(a > 10)

throw new KlasaIzuzetak(a);

System.out.println(„Normalan izlazak“);

}

public static void main(String args[]) {

try {

Obradi(1);

Obradi(20);

} catch (KlasaIzuzetak e) {

System.out.println(„Uhvacen: “ + e);

}

}

}

Rezultat ovog programa je:

Pozvana obrada(1)
Normalan izlazak
Pozvana obrada(2)
Uhvacen: Klasa izuzetak[20]

Polimorfizam i redefinisanje metoda

Polimorfizam i redefinisanje metoda

Redefinisanje metoda omogućava polimorfizam u trenutku izvršavanja. Polimorfizam omogućava da opšta klasa definiše metode koje će biti zajedničke za sve klase koje su iz nje izvedene, ostavljajući potklasama slobodu da definišu specifične varijante nekih ili svih pomenutih metoda. Posmatrajmo sledeće tri klase:

class Instrument {

abstract void sviraj();

}

class Violina extends Instrument {

void sviraj() {…}

}

class Klarinet extends Instrument {

void sviraj () {…}

}

Class Muzicar {

void sviraj (Instrument i) {

i . sviraj ();

}

}

Kada metoda potklase ima isto ime i tip kao neka 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 koja je definisana u natklasi će biti skrivena.

Dakle, prethodni primer definiše tri klase: klasa Instrument je apstraktna klasa (njena metoda sviraj je apstraktna), a klase Violina i Klarinet nasleđuju klasu Instrument i, naravno, implementiraju (redefinišu) apstraktnu metodu. Posmatrajmo sada klasu Muzicar:

Class Muzicar {

void sviraj (Instrument i) {

i . sviraj ();

}

}

Vidimo da klasa Muzičar ima metodu sviraj, koja kao parametar ima instancu klase Instrument; sa druge strane, znamo da klasa Instrument ne može imati instance jer je apstraktna.

Metoda sviraj će ipak biti upotrebljiva, jer se njoj kao parametar može proslediti instanca neke klase koja nasleđuje klasu Instrument, u ovom slučaju – instance klasa Violina i Klarinet. Iskaz:

Muzicar m = new Muzicar();

m.sviraj (new Klarinet());

izazvaće pozivanje metode sviraj klase Klarinet (iako se to nigde eksplicitno ne navodi u metodi sviraj klase Muzicar). Iskaz:

m. sviraj (new Violina());

izazvaće pozivanje metode sviraj klase Violina po istom principu. Dakle, poziv metode sviraj klase Muzicar će imati različite efekte zavisno od toga koji objekat prosledimo kao parametar. Određivanje koja metoda će se pozvati obavlja se u toku izvršavanja programa.

Pogledajmo sledeći primer:

class A {

int i, j;

A(int a, int b) {

i = a;

j = b;

}

void show() {

System.out.println(„i and j: “ + i + “ “ + j);

}

}

class B extends A {

int k;

B(int a, int b, int c) {

super(a, b);

k = c;

}

// Prikazuje k – ovim se redefinise metoda show() u A

void show() {

System.out.println(„k: “ + k);

}

}

class Override {

public static void main(String args[]) {

B subOb = new B(1, 2, 3);

subOb.show(); // poziva metodu show() u B

}

}

Rezultat programa će biti:

k: 3.

Ukoliko se želi izbeći redefinisanje metoda, tada se koristi rezervisana reč final. Već je bilo reči da final služi za pravljenje konstanti, međutim, ona se odnosi i na nasleđivanje. Da bi onemogućili redefinisanje određene metode, na početak njene deklaracije se stavlja modifikator final. Metode koje su označene kao final se ne mogu redefinisati. Ukoliko se želi sprečiti i nasleđivanje određene klase, to se takođe može postići stavljanjem rezervisane reči final ispred deklaracije te klase.

Nasledjivanje

Nasleđivanje

Nasleđivanje, kao jedan od osnovnih koncepata objektno-orijentisanog programiranja, postoji i u Javi. Nasleđivanje omogućava pravljenje hijerarhijske klasifikacije. Pomoću nasleđivanja može se napraviti opšta klasa koja definiše zajedničke karakteristike za skup srodnih pojava. Ovu klasu zatim mogu da naslede druge, specifičnije klase, pri čemu svaka dodaje ono što je za nju jedinstveno. Klase se nasleđuju tako što se definicija jedne klase umetne u drugu pomoću rezervisane reči extends. Pogledajmo primer gde klasa B nasleđuje klasu A.

class A {

int i,j;

}

class B extends A {

int k;

}

Može se zaključiti da je opšti oblik nasleđivanja:

Class imepotklase extends imenatklase {

// telo klase

}

Mada potklasa sadrži sve članove svoje natklase, ona ne može da pristupi onim članovima svoje natklase koji su označeni kao privatni (engl. private). Pogledajmo još jedan primer gde klasa BorbeniAvion nasleđuje klasu Avion:

class Avion {

Krilo levo, desno;

void poleti() {…}

void sleti() {…}

}

class BorbeniAvion extends Avion {

Top top;

Bomba bombe[];

void poleti(){…}

void pucaj(){…}

}

Java ne dopušta višestruko nasleđivanje (onako kako je to definisano, recimo, u jeziku C++). Dakle, klasa može da nasledi najviše jednu klasu.

2.7.1. Rezervisana reč super

Ponekad je potrebno da napravite natklasu koja detalje rada čuva za sebe, odnosno sa članovima ka kojima je dozvoljen samo privatan pristup. Kad god potklasa treba da se obrati svojoj neposrednoj natklasi, ona to može da učini pomoću rezervisane reči super. Ova rezervisana reč ima dva opšta oblika. Prvi poziva konstruktor natklase, dok se drugi koristi za pristupanje članu natklase koji je bio skriven članom potklase.

Potklasa može da pozove metodu konstruktora definisanu natklasom, koristeći sledeći opšti oblik:

super (lista parametara);

Lista parametara označava parametre koji su eventualno potrebni konstruktoru natklase. Kada potklasa pozove metodu super(), ona u stvari poziva konstruktor svoje neposredne natklase. Prema tome, metoda super() se uvek odnosi na natklasu neposredno iznad klase koja je poziva.

Drugi oblik upotrebe rezervisane reči super je najprimenljiviji kada imena članova potklase sakrivaju članove sa istim imenom u natklasi. Njen opšti oblik je:

super.član

Pogledajmo sledeći primer hijerarhije klasa:

class A {

int i;

}

// Pravljenje potklase proširenjem klase A.

class B extends A {

int i; // ovo i skriva i u klasi A

B(int a, int b) {

super.i = a; // i u klasi A

i = b; // i u B

}

void show() {

System.out.println(„i u natklasi: “ + super.i);

System.out.println(„i u podklasi: “ + i);

}

}

class UseSuper {

public static void main(String args[]) {

B subOb = new B(1, 2);

subOb.show();

}

}

Program prikazuje sledeći rezultat:

i u natklasi: 1

i u potklasi: 2

Razmotrimo još jedan primer za slučaj da je klasa Osoba apstraktna klasa, a klasa Student njena konkretna klasa.

import java.util.*;

abstract class Osoba{

String MLB;

String ImePrezime;

String Adresa;

Osoba (String MLB1,String ImePrezime1,String Adresa1) {

MLB=MLB1;

ImePrezime=ImePrezime1;

Adresa=Adresa1;

}

void Prikazi(){

System.out.println(„MLB: “ + MLB + “ Ime i prezime: “ + ImePrezime + “ Adresa:“ + Adresa);

}

}

class Student extends Osoba {

String BrojIndeksa;

int Godina;

Student (String MLB1, String ImePrezime1, String Adresa1,

String BrojIndeksa1, int Godina1) {

super (MLB1, ImePrezime1, Adresa1);

BrojIndeksa = BrojIndeksa1;

Godina = Godina1;

}

void Prikazi(){

super.Prikazi();

System.out.println(„Broj indeksa: “ + BrojIndeksa + “

Godina: “ + Godina);

}

}

class Glavna {

public static void main(String args[]) {

/* Osoba o = new Osoba(„1808971715553“,“Mika

Mikic“, „Nusiceva 5“); Ne moze da ima

pojavljivanja.*/

Student k1 = new Student („2502975716662“, „Pera

Peric“, „Beogradska 1“, „F123/02“,3);

k1.Prikazi();

}

}

Rezultat ovog programa je sledeći:

MLB: 2502975716662 ImePrezime: Pera Peric Adresa: Beogradska 1

BrojIndeksa: F123/02 Godina:3

2.7.2. Modifikatori pristupa

U Javi postoje sledeća tri modifikatora pristupa:

1. public: označava da su atribut ili metoda vidljivi za sve klase u programu;

2. protected: atribut ili metoda su vidljivi samo za klase naslednice;

3. private: atribut ili metoda su vidljivi samo unutar svoje klase.

Modifikatori pristupa se navode ispred definicije metode ili atributa. Sledi primer:

class Avion{

protected Krilo levo, desno;

public void poleti() {…}

public void sleti() {…}

}

Na sličan način modifikatori pristupa se mogu primeniti i na celu klasu, na primer:

public class Avion {…}

2.7.3. Zadatak za vežbu nasleđivanja klasa

Programski zahtev 1: pokazati odnos izmedu nadklase i podklase na primeru klasa Osoba (natklasa) i Student (potklasa).

import java.util.*;

class Osoba {

String MLB;

String ImePrezime;

String Adresa;

Osoba(){

MLB =““;

ImePrezime=““;

Adresa=““;

}

Osoba(String MLB1, String ImePrezime1, String Adresa1) {

MLB=MLB1;

ImePrezime=ImePrezime1;

Adresa=Adresa1;

}

void Prikazi(){

System.out.println(„MLB: “ + MLB + “ Ime i prezime: “ +

ImePrezime + “ Adresa:“ + Adresa);

}

}

class Student extends Osoba {

String BrojIndeksa;

int Godina;

Student(){

BrojIndeksa=““;

Godina=0;

}

Student (String MLB1, String ImePrezime1, String Adresa1, String

BrojIndeksa1, int Godina1) {

Super (MLB1, ImePrezime1, Adresa1);

BrojIndeksa = BrojIndeksa1;

Godina = Godina1;

}

void Prikazi(){

super.Prikazi();

System.out.println(„Broj indeksa: “ + BrojIndeksa + “ Godina:

“ + Godina);

}

}

class Glavna {

public static void main(String args[]) {

Student k = new Student();

k.Prikazi();

Student k1 = new Student(„2502975716662“,“Pera

Peric“,“Beogradska 1″,“F123/02″,3);

k1.Prikazi();

}

}

Rezultat:

MLB: ImePrezime: Adresa:

BrojIndeksa: Godina:

MLB: 2502975716662 ImePrezime: Pera Peric Adresa: Beogradska 1

BrojIndeksa: F123/02 Godina:3

Metode

Metode i njihovi parametri

Ako su vam bile nejasne metode, posle ovog posta verujem da će vam laknuti i da ćete shvatiti da Java nije bauk. Preporučujem da pre ovog posta procitate i prethodni o klasama, kako bi vam bilo jasnije. Kasnije ćemo naravno produbljivati znanje i nadovezivati klase, objekte, metode i konstruktore. Ali idemo polako jedno po jedno, i naravno strpljivo.

Kao što je ranije napomenuto, klase sadrže dve komponente: promenljive i metode. Opšti oblik deklarisanja metoda glasi:

Tip ime (lista parametara) {

// telo metode

}

Tip označava tip podatka koje metoda vraća. Ukoliko metoda ne vraća vrednost, njen tip povratnih podataka mora da bude označen sa void. Ime metode je određeno identifikatorom ime. Lista parametara sadrži niz parova razdvojenih zarezima. Parametri su promenljive koje prihvataju vrednosti argumenata prosleđenih metodi u trenutku njenog pozivanja. Metoda vraća vrednost koja se zadaje pomoću naredbe return, koja je oblika: return vrednost.

Može se ukratko reći da metode definišu pristup podacima u većini klasa. Pogledajmo primer sa klasom Kutija, koju ćemo proširiti tako što ćemo dodati metodu u okviru koje će se izračunavati zapremina.

class Kutija {

double sirina;

double visina;

double dubina;

// prikazuje zapreminu kutije

void zapremina() {

System.out.print(„Zapremina je „);

System.out.println(sirina * visina * dubina);

}

}

class KutijaDemo1 {

public static void main(String args[]) {

Kutija mojaKutija1 = new Kutija();

Kutija mojaKutija2 = new Kutija();

/* dodeljuje vrednosti promenljivama instanci objekta mojaKutija1 */

mojaKutija1.sirina = 10;

mojaKutija1.visina = 20;

mojaKutija1.dubina = 15;

/* dodeljuje vrednosti promenljivama

instanci objekta mojaKutija2*/

mojaKutija2.sirina = 3;

mojaKutija2.visina = 6;

mojaKutija2.dubina = 9;

// prikazuje zapreminu prve kutije

mojaKutija1.zapremina();

// prikazuje zapreminu druge kutije

mojaKutija2.zapremina();

}

}

Ovaj program ispisuje sledeće:

Zapremina je 3000.0

Zapremina je 162.0

Kao što se moglo uočiti svaki put kada se pozove metoda zapremina(), prikazuje se zapremina određene kutije.

Ukoliko deo programa ne želi da prikazuje zapreminu na ekranu, već samo da sazna njenu vrednost, onda će metoda zapremina izgledati ovako:

Double zapremina (){

Return sirina*visina*dubina;

}

U okviru klase, poziv na metodu zapremine izgledaće:

Double zapremina;

zapremina=mojaKutija1.zapremina()

system.out.println («Zapremina je + zapremina);

2.6.1. Parametarske metode

Prethodni primer bi mogao da se još više uprosti, i to pomoću metoda koji preuzimaju parametre. Rekli smo da je parametar promenljiva definisana metodom koja pri pozivanju metode prihvata vrednost. Na sledećem primeru:

Int kvadrat (int i) {

Return i*i;

}

parametar predstavlja i, dok je argument vrednost koja se prosleđuje metodi pri njenom pozivanju. Na primer, x=kvadrat(5) prosleđuje vrednost 5 kao argument. Parametar i unutar metode kvadrat() preuzima tu vrednost.

Koristeći parametarske metode, prethodni primer će izgledati:

class Kutija {

double sirina;

double visina;

double dubina;

double zapremina() {

return sirina * visina * dubina;

}

// dodeljivanje dimenzija kutije

void postaviDim(double s, double v, double d) {

sirina = s;

visina = v;

dubina = d;

}

}

class KutijaDemo2 {

public static void main(String args[]) {

Kutija mojaKutija1 = new Kutija();

Kutija mojaKutija2 = new Kutija();

double zapremina;

// inicijalizovanje svake kutije

mojaKutija1.postaviDim(10, 20, 15);

mojaKutija2.postaviDim(3, 6, 9);

// prikazivanje zapremine prve kutije

zapremina = mojaKutija1.zapremina();

System.out.println(„Zapremina je “ + zapremina);

// Prikazivanje zapremine druge kutije

zapremina = mojaKutija2.zapremina();

System.out.println(„Zapremina je “ + zapremina);

}

}

Kao što se vidi, za dodeljivanje dimenzija svake od kutija koristi se metoda postaviDim. Argumenti se kopiraju u parametre metode postaviDim, u okviru koje se vrednosti s, v i d dodeljuju promenljivama sirina, visina i dubina.

Zadatak za vežbu deklarisanja parametarskih metoda

Programski zahtev: napisati parametarsku metodu klase Automat Novca nazvanu Ulaganje i neparametarsku metodu nazvanu Prikazi.

import java.util.*;

class AutomatNovca {

String ImeKlijenta;

double Stanje;

void Ulaganje (double Stanje1) {

Stanje = Stanje1;

}

void Prikazi() {

System.out.println(„Stanje: “ + Stanje);

}

public static void main(String args[]) {

AutomatNovca k = new AutomatNovca();

k.Ulaganje(1300);

k.Prikazi();

}

}

Rezultat programa je:

Stanje: 1300.0

2.6.2. Konstruktori

S obzirom da nije dobro inicijalizovati sve promenljive unutar klase svaki put kada se stvori neka instanca, već je lakše i elegantnije da se sva podešavanja obave u trenutku kada je objekat prvi put napravljen, Java omogućava da objekti sami sebe inicijalizuju pri stvaranju. Ova automatska inicijalizacija se obavlja pomoću konstruktora.

Konstruktor inicijalizuje objekat odmah nakon njegovog stvaranja. On nosi isto ime kao i klasa u kojoj se nalazi, a po sintaksi je sličan metodi. Konstruktor se automatski poziva čim se napravi objekat, pre nego što operator new završi svoj posao. Konstruktori nemaju ni tip povratnih podataka ni tip void, zbog toga što je podrazumevani tip povratnih podataka konstruktora sam tip klase.

Zadatak konstruktora je da inicijalizuje unutrašnje stanje objekta tako da kôd koji pravi instancu odmah naiđe na potpuno inicijalizovan, upotrebljiv objekat. Da bi iskoristili prethodni primer za prikazivanje konstruktora, metodu postaviDim() ćemo zameniti konstruktorom.

class Kutija {

double sirina;

double visina;

double dubina;

// Ovo je konstruktor za kutiju

Kutija() {

System.out.println(„Konstruisem objekat klase Kutija „);

sirina = 10;

visina = 10;

dubina = 10;

}

// izračunava i vraća vrednosti zapremine

double zapremina() {

return sirina * visina * dubina;

}

}

class KutijaDemo3 {

public static void main(String args[]) {

/* deklariše, dodeljuje i inicijalizuje objekte

klase Kutija */

Kutija mojaKutija1 = new Kutija();

Kutija mojaKutija2 = new Kutija();

double zapremina;

// prikazivanje zapremine prve kutije

zapremina = mojaKutija1.zapremina();

System.out.println(„Zapremina je “ + zapremina);

// prikazivanje zapremine druge kutije

zapremina = mojaKutija2.zapremina();

System.out.println(„Zapremina je “ + zapremina);

}

}

Rezultat ovog programa, pri njenom izvršavanju je:

Konstruisem objekat klase Kutija

Konstruisem objekat klase Kutija

Zapremina je 1000.0

Zapremina je 1000.0

Konstruktor Kutija() inicijalizuje objekte mojaKutija1 i mojaKutija2 čim se stvore, i dodeljuje ima iste dimenzije: 10x10x10. Kada se konstruktor izričito ne definiše, Java će za klasu iskoristiti podrazumevani konstruktor koji automatski sve promenljive instanci inicijalizuje vrednošću nula.

U prethodnom primeru smo svim kutijama dodelili iste dimenzije, a ukoliko to ne želimo, onda ćemo koristiti parametarske konstruktore. Na primer, u sledećoj verziji programa Kutija definišemo parametarski konstruktor koji dimenzijama dodeljuje vrednosti zadate preko parametara.

class Kutija {

double sirina;

double visina;

double dubina;

// Ovo je konstruktor klase kutija

Kutija(double s, double v, double d) {

sirina = s;

visina = v;

dubina = d;

}

double zapremina() {

return sirina * visina * dubina;

}

}

class KutijaDemo4 {

public static void main(String args[]) {

Kutija mojaKutija1 = new Kutija (10, 20, 15);

Kutija mojaKutija2 = new Kutija (3, 6, 9);

double zapremina;

zapremina = mojaKutija1.zapremina();

System.out.println(„Zapremina je “ + zapremina);

zapremina = mojaKutija2.zapremina();

System.out.println(„Zapremina je “ + zapremina);

}

}

Rezultat je sledeći:

Zapremina je 3000.0

Zapremina je 162.0

Kao što se vidi, svaki objekat se inicijalizuje vrednostima parametara konstruktora koji se prosleđuju konstruktoru Kutija u trenutku kada operator new pravi objekat.

Zadatak za vežbu deklarisanja konstruktora

Programski zahtev: napisati default i parametarski konstruktor klase AutomatNovca.

import java.util.*;

class AutomatNovca {

String ImeKlijenta;

double Stanje;

AutomatNovca(){

ImeKlijenta = „nepoznato“;

Stanje = 0;

}

AutomatNovca(String ImeKlijenta1, double Stanje1){

ImeKlijenta = ImeKlijenta1;

Stanje = Stanje1;

}

void PrikaziKlijenta(){

System.out.println(„Ime klijenta: “ + ImeKlijenta + “ Stanje:“ + Stanje);

}

public static void main(String args[]) {

AutomatNovca k = new AutomatNovca();

AutomatNovca k1 = new AutomatNovca(„Pera Peric“, 3500);

AutomatNovca k2 = new AutomatNovca();

k.PrikaziKlijenta();

k1.PrikaziKlijenta();

k2.PrikaziKlijenta();

}

}

Rezultat ovog programa pri njenom izvršavanju je:

Ime Klijenta: nepoznatno Stanje = 0.0

Ime Klijenta: Pera Peric Stanje = 3500.0

Ime Klijenta: nepoznatno Stanje = 0.0

2.6.3. Rezervisana reč this

Ponekad je potrebno da metoda ukaže na objekat koji ju je pozvao. Java ovo omogućava pomoću rezervisane reči this, koja se može koristiti unutar bilo koje metode da bi se ukazalo na tekući objekat. Znači, reč this je uvek referenca na objekat za koji je pozvana metoda. Pogledajmo sledeći primer koji koristi rezervisanu reč this:

import java.util.*;

class AutomatNovca {

String ImeKlijenta;

double Stanje;

void Ulaganje (double Stanje1) {

this.Stanje = Stanje1;

}

void Prikazi() {

System.out.println(Stanje);

}

public static void main(String args[]) {

AutomatNovca k = new AutomatNovca();

AutomatNovca k1 = new AutomatNovca();

k.Ulaganje(1300);

k1.Ulaganje(1500);

k.Prikazi();

k1.Prikazi();

}

}

Rezultat ovog programa je:

1300.0

1500.0

Unutar konstruktora Ulaganje, reč this će uvek ukazivati na objekat koji poziva metodu.

2.6.4. Ključna reč final

Ključna reč final se može naći ispred definicije atributa ili metode unutar definicije klase. Ako se nađe ispred atributa, označava atribut kome nije moguće promeniti vrednost. Drugim rečima, final atribut predstavlja konstantu. Inicijalizacija prilikom deklaracije atributa je obavezna. Primer definicije jednog final atributa bio bi:

final int VELICINA = 100;

Ključna reč final ima drugo značenje kod metoda: označava metode koje se ne mogu redefinisati prilikom nasleđivanja date klase. Primer jedne final metode glasi:

final int metoda(int i){…}

2.6.5. Ključna reč static

Ponekad je potrebno definisati član klase koji će se koristiti nezavisno od objekata klase. Članu klase obično se može pristupati samo preko objekta iste klase. Međutim, moguće je napraviti i član koji se samostalno može koristiti, bez referenciranja određene instance.

Kada želite da napravite takav član, njegovu deklaraciju započnite rezervisanom rečju static. Kada član bude statičan, njemu će moći da se pristupi pre nego što bude napravljen ijedan objekat njegove klase i bez referenciranja bilo kog objekta. Takođe, i metode mogu biti statične. Najpoznatiji primer statične metode je main(). Promenljive instanci deklarisane kao statične su, u suštini, globalne promenljive.

Pogledajmo sledeći programski zahtev koji ilustruje kako static atribut Stanje klase KStanje dele dva različita objekta klase KStanje.

class AutomatNovca {

public static void main(String args[]) {

KStanje k = new KStanje();

k.Prikazi();

k.Stanje = 5;

k.Prikazi();

KStanje k1 = new KStanje();

k.Prikazi();

k1.Stanje = 7;

k.Prikazi();

}

}

class KStanje {

static double Stanje;

void Prikazi(){

System.out.println(„Vrednost stanja je: “ + Stanje);

}

static{ Stanje = 2;}

}

Rezultat ovog programa je sledeći:

Vrednost stanja je: 2.0

Vrednost stanja je: 5.0

Vrednost stanja je: 5.0

Vrednost stanja je: 7.0

2.6.6. Metoda finalize

Prethodno smo naveli da se objektima memorija dodeljuje dinamički pomoću operatora new, dok se brisanje nepotrebnih objekata obavlja automatski tehnikom sakupljanje smeća (engl. Garbage collection – GC). Ova tehnika radi tako što kada nema nijedne reference na neki objekat, pretpostavlja da taj objekat više nije potreban i da memorija koju zauzima može da postane raspoloživa.

Različiti Javini izvršni sistemi koristiće različite pristupe sakupljanju smeća. Pored automatske dealokacije memorije, GC je zadužen i za automatsku defragmentaciju memorije. U trenutku dealokacije podrazumeva se da je Java objekat oslobodio ostale resurse koje je koristio (otvorene datoteke, mrežne konekcije, itd.).

Ponekad objekat pre nego što se uništi treba da izvrši neku akciju.Ovo se postiže definisanjem metode finalize, čiji je opšti oblik:

Protected void finalize ()

{

// kôd za finalizaciju

}

Ključna reč protected predstavlja specifikator koji sprečava pristupanje metodi spolja. Metoda finalize će biti pozvana neposredno pre sakupljanja smeća. Ovde je važno naglasiti da metodu finalize ne treba koristiti za oslobađanje zauzetih resursa, jer se metoda finalize ne mora pozvati. Naime, GC sam određuje kada će ukloniti objekat iz memorije i lako se može desiti da se to nikad ne dogodi: program je pokrenut, radio je neko vreme, računar raspolaže sa dovoljno radne memorije, tako da GC nije počeo sa uklanjanjem objekata, i tako sve do završetka rada programa; GC nije uklonio objekat, samim tim nije pozvao metodu finalize i eventualno oslobađanje zauzetih resursa se nije ni desilo.