Java

Mureakuha

Loikkaa: valikkoon, hakuun

Sisällysluettelo

Javan historia

Java on Sun Microsystems, Inc.:n kehittämä laitteistoriippumaton oliopohjainen ohjelmointikieli. Sen laitteistoriippumattomuus on saatu aikaan kääntämällä ohjelmat ns. virtuaalikoneen koodiksi (= "tavukoodi", engl. byte code), jota virtuaalikone tulkkaa muuntamalla tavukoodin lennossa varsinaisen tietokoneen suorittimen ymmärtämiksi konekielikäskyiksi.

Java-kielen 1990-luvun lopulla saavuttaman suuren suosion takana ovat laitteistoriippumattomuuden lisäksi kielen C++-kieltä läheisesti muistuttava, mutta helpommin omaksuttavaksi suunniteltu kielioppi, oliopohjaisuus ja virtuaalikoneen mukana tuleva, erittäin kattava standardikirjasto. Myös muistinhallintaa on helpotettu ottamalla käyttöön muistikeräin (engl. garbage collector), joka vapauttaa muistia kun sitä ei enää tarvita.

Koska Java-ohjelmat ajetaan virtuaalikoneessa, ne eivät normaalisti pysty vaikuttamaan suoraan muihin prosesseihin, eivätkä pääse virtuaalikoneelle määrätyn hiekkalaatikon ulkopuolelle vaan esimerkiksi kovalevyä käytettäessä käskyt kulkevat virtuaalikoneen läpi, joka varmistaa ettei käsky ole hiekkalaatikon ulkopuolella. Java-ohjelmat ovat mm. näiden rajoitusten vuoksi tavanomaisia konekieliohjelmia turvallisempia, mutta samalla hieman hitaampia.

Kieltä käytetään paljon dynaamisia WWW-sivuja tehtäessä (JSP, servlet), raskaissa palvelinsovelluksissa (J2EE), kännyköissä (J2ME), taskutietokoneissa, ja jonkin verran myös käyttäjien selaimissa toimivissa sovelmissa. Myöskin isoja käyttöliittymiä tehdään Javalla paljon. Yleisyytensä vuoksi se on myös suosittu opetuskieli.

Java kuuluu ohjelmointikieliin, joissa on käytössä ns. vahva tyypitys. Tämä tarkoittaa sitä, että jokaisella muuttujalla on tyyppi ja muuttujat voivat saada ainoastaan tyyppinsä mukaisia arvoja.

Java on saanut nimensä Jaavan saaren (Indonesiassa) mukaan, sillä kyseisellä saarella tuotetaan kahvilajia, jota Java-kielen kehittäjät nauttivat suuria määriä kieltä suunnitellessaan ja toteuttaessaan. Sekaannusten välttämiseksi ohjemointikielen nimen oikeinkirjoitus on tärkeää, jottei se sekaannu Jaavan saarella puhuttuun jaavan kieleen.


Javan alkeet

Ohjelmien kirjoittaminen Javalla

Perinteinen HelloWorld -esimerkki

HelloWorld-esimerkki javalla

public class HelloWorld {
  public static void main(String args[]) {
    System.out.println("Hello World!");
  }
}

Tarvittavat ohjelmat

Javan kehitykseen on runsaasti sekä avoimia, että kaupallisia ohjelmia.

Avoimet tai muuten ilmaiset
EclipseAvoin ja tehty javalla, joten toimii useissa käyttöjärjestelmissä
JEditTehty Javalla
TextPadWindowsissa toimiva tekstieditori, joka osaa Javan syntaksin värityksen

Tunnukset

Muuttujat

Javassa muuttujat määritellään seuraavasti

LuokanNimi muuttujanNimi;

Edellinen esimerkki luo muuttujan, jonka nimi olisi "muuttujanNimi". Joillakin on tapana kirjoittaa muuttujien nimet alkaen pienellä kirjaimella, kun taas luokkien nimet alkamaan isolla kirjaimella. Tällä tavalla saadaan luokat ja muuttujat helposti eroteltua toisistaan.

Muuttujaan voidaan tallentaa olion osoite luomalla siihen olio tai tuomalla toisesta muuttujasta viittaus.

LuokanNimi muuttujanNimi = new LuokanNimi(parametreja);
//tai viittauksen tuominen
LuokanNimi muuttujanNimi2 = muuttujanNimi;

Nyt molemmat muuttujat viittaavat samaan olion. Poikkeuksen viittauksesta tekevät perustietotyypit kuten int, double ja char. Kyseisten luokkien kohdalla tallennetaan muuttujaan arvo, eikä viittausta.

Perustyypit

Alkeistietotyypit
Tietotyyppi Selitys Koko (bit) Arvoalue
byte tavu 8 -128 -> 127
short kokonaisluku 16 -32768 -> 62767
int kokonaisluku 32 -2147483648->2147483647
long kokonaisluku 64 -2^63->2^63
float liukuluku 32 IEEE 754
double liukuluku 64 IEEE 754
char unicode-merkki 16 yli 60'000 merkkiä
boolean totuus 8 true tai false

Merkkijonot

Yleisimpiä erikoismerkkejä  
Javan lyhyt merkki Unicode-merkki Selitys
\b \u0008 Askelpalautus
\n \u000A Rivinvaihto
\r \u000D Palautus rivin alkuun
\t \u0009 Sarkain
\\ \u005C Kenoviiva
\" \u0022 Lainausmerkki
\u0027 Puolilainaus
\O30   Oktaaliluku 30
  \u00C4 Ä
  \u00E4 a
  \u00D6 Ö
  \u00F6 ö
  \u00C5 Å
  \u00E5 å
     
     
     

Vakiot

Laskeminen

Javassa voidaan laskea peruslaskutoimitukset kuten laskimissa.

int tulos = 5+6*7/2;

Edellinen esimerkki tallentaa vastauksen kokonaislukumuuttujaan, jolloin desimaaliosa ei pyöristy vaan leikkantuu pois.

Laskemisssa voidaan käyttää apuna myös muuttujia. Laskettu tulos voidaan tallentaa muuttujaan, joka on laskutehtävässä mukana. Laskujärjestys on normaalisti vasemmalta oikealle ja kerto/jakolaskut suoritetaan ensin.

double a = 5.482;
double b = 5.482;
a = a*b;

Sama voidaan tehdä myös pikaoperaattorilla

double a = 5.482;
double b = 5.482;
a*=b; //sama kuin a = a * b
//tai muita samankaltaisia
a/=b; //sama kuin a = a / b
a+=b; //sama kuin a = a + b
a-=b; //sama kuin a = a - b 
 

Ohjelmoidessa joudutaan usein lisämään tai vähentämään arvoa yhdellä. Tätä tehtävää varten javassa on pikaoperaattoreita, joita kannattaa käyttää myös laskentatehollisista syistäkin.

int i = 1;
int a = i++; //a=1 ja i=2, koska kasvatus tehdään sijoittamisen jälkeen.
 
int u = 1;
int b = ++u; //b=2 ja u=2, koska kasvatus tehdään sijoittamista ennen. 
 

Edellä esitettyä tapaa käytetään usein FOR-silmukoiden yhteydessä.

Javassa on käytettävissä matemaattisia funktioita, jotka löytyvät java.lang.Math luokasta. Funktiot ovat staattisia, joten niiden käyttö onnistuu helposti staattista importtia käyttäen.

static import java.lang.Math.*;
 
public class Esimerkki
{
   public static void Main(String[] args)
   {
      float f = 8.5f;
      double d = sin(f) * PI;
   }
}

Tekstinkäsittely

Tietojen syöttäminen ohjelmalle

Tietojen tulostaminen

System.out luokan avulla konsolissa

Formatoitu tulostaminen

Java 5.0 mahdollistaa tulostuksen muotoiluun C:n printf-funktiota muistuttavalla tavalla.

String nimi = "Kalle Kuusisto";
int ika = 55;
System.out.printf("Nimi: %s%nIkä: %d", nimi, ika);

Formatoidussa tekstissä konversiomerkin %s ja %d kertovat tyypin. Sen jälkeen tulee argumentteja muotoilulle. Indeksin voisi määritellä esim. %2$f.2€ Tämä tarkoittaisi sitä, että otetaan toinen argumentti, jonka tyyppi on liukuluku ja kahden desimaalin tarkkuudella ja euron merkki sitten normaalina tekstinä.

%[indeksi$][liput][.tarkkuus]konversio

Konversio tunnukset

  • d //Kokonaisluku kymmenjärjestelmässä
  • f //Liukuluku
  • e //Liukuluku kymmenpotenssimuodossa
  • n //Rivinvaihto
  • x //Kokonaisluku heksaluvuksi
  • s //Merkkijono
  • c //Unicode-merkki
  • % //Prosenttimerkin tulostaminen

Lippuja

  • - //Tulostaa kentän vasempaan reunaan
  • + //Etumerkki lukuihin
  • 0 //Nollia luvun eteen


Javan documentaatiossa java.io.PrintStream

Esimerkkejä http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Tech/Chapter05/formatterPrintf.html

Kommentit

Ehtolauseet

IF Jos näin tee niin

IF...ELSE Jos ei näin, tee toisin

if (response == OK) {
    //code to perform OK action
} else {
    //code to perform Cancel action
}
if (ika >= 90) {
    selitys = 'Wanha';
  } else if (ika >= 80) {
    selitys = 'Naisen iässä';
  } else if (ika >= 70) {
    selitys = 'Miehen iässä';
  } else if (ika >= 60) {
    selitys = 'Eläkkeelle';
  } else {
    selitys = 'Nuori';
  }
  System.out.println("Olet = " + selitys);
}

SWITCH..CASE Valitse tehtävä työ

Javassa case:n arvon on, samoin kuin C:ssäkin, oltava vakio.

int month = 8;
switch (month) {
  case 1:  System.out.println("January"); break;
  case 2:  System.out.println("February"); break;
  case 3:  System.out.println("March"); break;
  case 4:  System.out.println("April"); break;
  case 5:  System.out.println("May"); break;
  case 6:  System.out.println("June"); break;
  case 7:  System.out.println("July"); break;
  case 8:  System.out.println("August"); break;
  case 9:  System.out.println("September"); break;
  case 10: System.out.println("October"); break;
  case 11: System.out.println("November"); break;
  case 12: System.out.println("December"); break;
  default: System.out.println("Not a month!");break;
}

Silmukat

FOR Tee jotakin niin kauan kuin x on tosi

for(int i=0;i<10;i++)
{
   System.out.println(i.toString());
}

tulostaa:0,1,2,3,4,5,6,7,8,9

Keskeytä toisto

for(int i=0;i<10;i++)
{
   if(i>5) break; //Lopettaa silmukan kun i on suurempi, kuin 5
   System.out.println(i.toString());
}

tulostaa: 0,1,2,3,4,5

Aloita toisto alusta

for(int i=0;i<10;i++)
{
   if(i==5) continue //Hyppää tulostuksen yli, kun i on viisi
   System.out.println(i.toString());
}

Tulostaa 0,1,2,3,4,6,7,8,9

FOR (FOR...EACH): käy taulukon tai kokoelman alkiot läpi

JDK 1.5.0:ssa esitellyllä for each -rakenteella voidaan käydä helposti läpi taulukoiden tai Iterable-rajapinnan toteuttavien luokkien alkioita.

Esimerkki taulukon ja kokoelman läpikäymisestä

String[] nimilista = {"Kalle","Jaakko","Jussi"};
for(String nimi: nimilista) {
   System.out.println(nimi);
}
 
List<String> nimilista2 = Arrays.asList("Tiina", "Maija", "Kati");
for (String nimi: nimilista2) {
   System.out.println(nimi);
}

WHILE Tee jotakin, kunnes ehto on epätosi

while(i < 5)
{
i++;
}

Taulukot

Taulukko

Ennakkoon tiedossa olevan taulukon tekeminen;

String[] nimet = new String[2];
nimet[0] = "Teppo";
nimet[1] = "Matti";

Edeltävä esimerkki määrittää ensimmäisellä rivillä String-oliotaulukon, jossa on kaksi lokeroa. Lokerointi alkaa aina nollasta, joten viimeisen lokeron numero on yhden vähemmän kuin mitä lokeroita on.

Taulukkoon voi myös antaa tiedot alustuksessa

String[] nimet = {"Matti", "Teppo"};
//Tai toisesta luokasta palauttaa taulukko
String[] nimilista = JokuOlio.GetNimiLista();

Taulukon koon muuttaminen onnistuu vain luomalla uusi suurempi taulukko ja vanhat tiedot saadaan säästettyä käyttämällä apuna väliaikaista taulukkoa

String[] nimet = {"Matti", "Teppo"};
String[] temp = nimet;
nimet = new String[3];
nimet[0] = "Uusi nimi";
int i = 1;
for(String nimi:temp)
{
   nimet[i++] = nimi;
}

Eli muuttuvamittaisten taulukoiden käyttäminen näin on rumaa ja hidasta, joten suosittelen kokoelmaolioiden käyttöä. Kokoelmaoliot etenkin JDK5.0:n geneeristen tyyppien jälkeen ovat päässeet oikeuksiinsa tehokkaina "taulukkolaajennuksina"

Kokoelmaoliot

Vanhoissa Java versioissa kokoelmaoliot luotiin näin

ArrayList nimet = new ArrayList();
nimet.Add("Teppo");
nimet.Add("Matti");
String nimi = (String)nimet.elementAt(1);

Tietojen lisääminen on helppoa, koska kaikki javan oliot on mahdollista tallentaa object-tyyppiseen muuttujaan, mutta niiden uudelleen käyttöönotto vaati tyyppimuunnoksen, joka näkyy viimeisellä rivillä.

JDK5.0:ssa sama tehtäisiin näin

ArrayList<String> nimet = new ArrayList<String>();
nimet.Add("Teppo");
nimet.Add("Matti");
String nimi = nimet.elementAt(1);

Kuten edellisestä esimerkistä selviää, on koodi lyhyempää ja selvempää ja kaiken lisäksi vielä tehokkaampaakin, kun ei tarvita tyyppimuunnoksia.

Kokoelmaluokat

Kokoelmaolioita on kirjoiteltu eri tarkoituksia varten useita, joista alla lista

Olio-ohjelmointia javalla

Staattinen import

static import java.lang.Math.*;
 
public class Esimerkki
{
   public static void Main(String[] args)
   {
      float f = 8.5f;
      double d = sin(f) * PI;
   }
}

Autoboxing/Autounboxing

JDK5:n myötä tuli pieni helpotus perustietotyyppien ja niiden olioversioiden hallintaan.

Integer i1 = new Integer(45);
//tai 5:n jälkeen myös
Integer i2 = 45;
//Myös sijoittelut ristiin onnistuu
int i3 = i2;
i3++;
i2 = i3;

Automaattiset tyyppimuunnokset nopeuttavat ohjelmointia, kun ei tarvitse kirjoittaa tyyppimuunnoskoodia, mutta on edelleen hidasta suorittaa, joten itse laskemisessa ei olioita kannata käyttää.

Vaihtuvamittainen parametrilista

public void MetodiVaihtuvallaParametriMaaralla(String kutsunSyy, String... kutsuttavat)
{
   System.out.println(kutsunSyy);
   System.out.println("-----------------");
   for(String nimi:kutsuttavat)
   {
      System.out.println(nimi);
   }
}

Luettelotyyppi

Javan documentaatiossa enum

Yleishyödyllisiä luokkia

Math

java.util

java.util.Scanner

Luokan avulla voidaan lukea esim. näppäimistön syötteitä.

Scanner nappis = new Scanner(System.in);
String kokoNimi = nappis.nextLine();
String tekstiä = nappis.next();
double d = nappis.nextDouble();
float f = nappis.nextFloat();
int i = nappis.nextInt();
nappis.Close(); //Muista sulkea aina 
 

java.io

java.text

Verkossa suomeksi

Verkossa englanniksi

Suomenkielinen kirjallisuus

Java 2 -ohjelmoinnin perusteet kirjoittanut:

  • Pekka Koskinen
  • Juha Peltomäki
  • Simo Silander

Julkaisija Docendo Finland Oy, Jyväskylä 2005 ISBN: 951-846-237-2

Arvostelu: Loistava käsikirjaksi toisesta kielestä siirtyvälle. Kirjan alussa lyhyt kertaus ohjelmoinnin alkeista, mutta ei riittävä opettaakseen ohjelmointa aloittelevalle.

Englanninkielinen kirjallisuus

Henkilökohtaiset työkalut