Ainoa Java- kielen tuntema parametrinvälitysmekanismi on parametrien välittäminen arvoina. Tämä tarkoittaa sitä, että aliohjelma saa käyttöönsä vain (luku)arvoja, ei muuta. Olkoon meillä esimerkiksi ongelmana tehdä aliohjelma, jolle viedään parametreinä tunnit ja minuutit sekä niihin lisättävä minuuttimäärä. Jos ensimmäinen yritys olisi seuraava:
/** :-( * Yritetään lisätä metodissa parametrien arvoja * @author Vesa Lappalainen * @version 1.0, 18.01.2003 */ public class Aikalisa { private static void lisaa(int h, int m, int lisa_min) { int yht_min = h*60 + m + lisa_min; h = yht_min / 60; m = yht_min % 60; } private static void tulosta(int h, int m) { System.out.println("" + h + ":" + m); } public static void main(String[] args) { int h=12,m=15; tulosta(h,m); lisaa(h,m,55); tulosta(h,m); } }
Tämä ei tietenkään toimisi! Hyvä (C-) - kääntäjä jopa varoittaisi että:
Warn : aikalisa.cpp(8,2):'m' is assigned a value that is never used Warn : aikalisa.cpp(7,2):'h' is assigned a value that is never used
Mutta miksi ohjelma ei toimisi? Seuraavan selityksen voi ehkä ohittaa ensimmäisellä lukukerralla. Tutkitaanpa tarkemmin mitä aliohjelmakutsussa oikein tapahtuu. Oikaisemme seuraavassa hieman joissakin kohdissa liian tekniikan kiertämiseksi, mutta emme kovin paljoa. Esimerkki on kirjoitettu vastaavasta C++-ohjelmasta. Javassa periaatteessa tapahtuu samalla tavalla. Katsotaanpa ensin miten kääntäjä kääntäisi aliohjelmakutsun ( Borland C++ 5.1, 32-bittinen käännös, rekisterimuuttujat kielletty jottei optimointi tekisi konekielisestä ohjelmasta liian monimutkaista):
lisaa(h,m,55); muistiosoite assembler selitys ------------------------------------------------------------------------- 004010F9 push 0x37 pinoon 55 004010FB push [ebp-0x08] pinoon m:n arvo 004010FE push [ebp-0x04] pinoon h:n arvo 00401101 call lisaa mennään aliohjelmaan lisää 00401106 add esp,0x0c poistetaan pinosta 12 tavua (3 x int)
Kun saavutaan aliohjelmaan lisaa, on pino siis seuraavan näköinen:
muistiosoite sisältö selitys ------------------------------------------------------------------------ 064FDEC 00401106 <-ESP paluuosoite kun aliohjelma on suoritettu 064FDF0 0000000C h:n arvo, eli 12 064FDF4 0000000F m:n arvo, eli 15 064FDF8 00000037 lisa_min, eli 55
Eli aliohjelmaan saavuttaessa aliohjelmalla on käytössään vain arvot 12,15 ja 55. Näitä se käyttää tässä järjestyksessä omien parametriensa arvoina, eli m,h,lisa_min.
Esimerkiksi Pascal ja C/C++ -kielissä olisi tarjota tähän sellainen ratkaisu, että aliohjelman parametrit olisivatkin viitteitä (tai osoittimia) kutsuvan ohjelman muuttujiin ja niihin tehty muutos muuttaisi suoraan kutsuvan ohjelman muuttujia. Javassa tämä on mahdollista vain olioille, koska oliot välitettiin viitteinä.
C++: void lisaa(int &h, int &m, int lisamin); kutsu: lisaa(h,m,55); Pascal: procedure lisaa(var h,m:integer; lisamin:integer); kutsu: lisaa(h,m,55); C: void lisaa(int *h, int *m, int lisamin); kutsu: lisaa(&h,&m,55)