1 / 22

7. Oliot ja viitteet

7. Oliot ja viitteet. Sisällys. Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden käsittelyä: sijoitus, vertailu ja varautuminen null -arvoon. Viite metodin paluuarvona. Viite metodin parametrina. Olio Java-kielessä.

jenski
Download Presentation

7. Oliot ja viitteet

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 7. Oliot ja viitteet

  2. Sisällys • Olio Java-kielessä. • Olion luominen, elinikä ja tuhoutuminen. • Viitteiden käsittelyä: • sijoitus, vertailu ja varautuminen null-arvoon. • Viite metodin paluuarvona. • Viite metodin parametrina.

  3. Olio Java-kielessä • Java-kielessä olio määritellään joko luokan edustajaksi tai taulukoksi. • Olio on joukko keskusmuistissa olevia tietoja. • Oliota käsitellään siihen epäsuorasti liittyvän viitetyyppisen muuttujan eli viitteen (reference) avulla. • Viite määrittää olion identiteetin. • Viite toteutetaan teknisesti yhden tai useamman suojatun osoittimen (pointer) avulla. • Javan viitteet eri asia kuin osoittimet ja C++:n viitteet.

  4. Olion luominen • Tunnuksen esittely varaa muistia viitteelle (viitetyyppiselle muuttujalle), mutta ei oliolle. • Java alustaa automaattisesti viitteen tyhjäksi (null-arvo) tai ilmoittaa, että viite on alustettava. • Oliolle varataan muistia new-operaatiolla, joka palauttaa viitteen. • Viitetyyppinen muuttuja ja olio liittyvät toisiinsa, kun new-operaation paluuarvona saatava viite sijoitetaan muuttujan arvoksi.

  5. null rontti olio olio rontti Olion luominen • Kissa rontti = null; • rontti = new Kissa(); Olion viitteen esittely ja alustaminen tyhjäksi. Lauseke new Kissa(); luo olion, alustaa sen attribuutit ja palauttaa paluu-arvona olioon liittyvän tunnuksettoman viitteen. Sijoituksen seurauksena rontti-viite viittaa samaan olioon kuin paluuarvona saatu viite.

  6. Olion elinikä • Olio on olemassa (“elää”) niin kauan kun siihen liittyy yksi tai useampia viitteitä. • Viitetyyppiset muuttujat “elävät” alkeistyyppisten muuttujien tapaan vain esittelylohkossaan: • Esimerkiksi metodissa esitelty viite tuhoutuu metodista poistuttaessa, koska sen tunnus on paikallinen. • Olion elinikä voi kuitenkin poiketa olioon muistinvarauksen yhteydessä asetetun viitteen eliniästä, koska olioon voidaan liittää myös muissakin lohkoissa kuin esittelylohkossa “eläviä” viitteitä.

  7. Olion tuhoutuminen • Olio tuhoutuu, kun siihen ei liity viitteitä. • Viitteettömien olioiden poistaminen hoidetaan automaattisesti Javan virtuaalikoneen toimesta. • Toimenpidettä kutsutaan roskankeruuksi (garbage collection). • Virtuaalikone kerää roskia automaattisesti, kun tarvitaan lisää muistitilaa. • Java-ohjelmoijan ei siis tarvitse huolehtia olioiden poistamisesta ohjelmallisesti.

  8. Olion tuhoutuminen • Javan virtuaalikonetta voi myös käskeä tuhoamaan tarpeettomat oliot System-luokan gc-metodilla. • Monissa kielissä varattu muisti vapautetaan ohjelmoijan toimesta erityisellä operaatiolla. • Operaattorin käyttö on tehokkaampaa kuin automaattinen muistin vapautus, mutta altistaa myös muistivuodoille (memory leak).

  9. Viitteiden sijoitus • Viitetyyppiseen muuttujaan x voidaan sijoittaa toinen viitetyyppinen muuttuja y lauseella x = y;, missä muuttujien x ja y tyyppi (luokka) on sopiva. • Sijoitus “irrottaa” viitteen x siihen mahdollisesti liittyvästä oliosta ja “kiinnittää” viitteen y:n olioon. • Sijoituksen jälkeen muuttuja x viittaa muuttujan y viittaamaan olioon. • Sijoitus ei kopioi y:n viittaaman olion tietoja x:n viittaaman olion tietojen päälle! (Tähän tarvitaan oma metodi.)

  10. a b a b A b x y x y x x x y Viitteiden sijoitus • Esim. Osoittakoon viite x olioon a ja y olioon b. Viitteiden tyyppi oletetaan samaksi. • Alkutilanne • Sijoitus x = y; • Lopputilanne

  11. Viitteiden sijoitus • Sijoituksen kautta yhteen olioon voi viitata useampia tunnuksia. • Olion identiteetti säilyy, vaikka olioon olisi useampia viitteitä, koska viitteet liittyvät samaan olioon. • Sijoituksen sivuvaikutuksena olioon ei välttämättä enää ole viitteitä, jolloin olio jää roskankerääjän saaliiksi. • Olion viitteet voidaan myös poistaa asettamalla ne tyhjiksi eli null-arvoisiksi.

  12. Viitteiden sijoitus public class ViiteTesti { public static void main(String[] args) { // Esitellään viitteet ja varataan muistia. String x = new String("a"); String y = new String("b"); // Kiinnitetään viite x viitteen y osoittamaan olioon. x = y; System.out.println(x + " " + y); // b b // Irrotetaan viitteet b-oliosta. x = y = null; System.out.println(x + " " + y); // null null } }

  13. Viitteiden vertailu • Viitetyyppisiä muuttujia voidaan myös vertailla yhtä- ja erisuuruusoperaattoreilla (== ja !=). • Vertailu kohdistuu viitteisiin eikä viitattuihin olioihin. • Olioiden sisällön vertailuun pitää kirjoittaa erillinen metodi. • equals- ja compareTo-metodit.

  14. Viitteiden vertailu public class VertailuTesti { public static void main(String[] args) { // Esitellään viitteet ja varataan muistia. String eka1 = new String("eka"); String eka2 = new String("eka"); // Vertaillaan viitteitä. System.out.println(eka1 == eka2); // false // Vertaillaan olioita. System.out.println(eka1.equals(eka2)); // true } }

  15. Tyhjät (null-arvoiset) viitteet • Metodin kutsu tyhjän viitteen kautta aiheuttaa ajonaikaisen virheen (poikkeuksen), joka pysäyttää ohjelman suorituksen. • Metodissa voi varautua null-arvoiseen parametriin joko if-lauseella: if (viite != null) { // Viite liittyy olioon, sitä voidaan käsitellä. } tai try-catch-lauseella: try { // Tällä käsitellään viitettä. Poikkeus siepataan tarvittaessa. } catch (NullPointerException e) { // Viite oli tyhjä. } • Tyhjää viitettä ei huomioida, jos voidaan olettaa, että tyhjän viitteen aiheuttama poikkeus käsitellään muualla.

  16. Viite metodin paluuarvona • Metodin tunnukset ovat paikallisia (lokaaleja) - ne ovat olemassa vain metodin suorituksen ajan. • Jos metodissa luotu olio halutaan säilyttää, voidaan sen viite palauttaa metodin paluuarvona ja paluu-arvo sijoittaa muuttujaan kutsuvassa metodissa. • Olio ei tuhoudu, vaikka paikallinen viite tuhoutuu, koska olioon asetetaan toisen lohkon viite. • Näin toimien paikallisesti esitelty olio “elää” alkuperäistä viitettään vanhemmaksi.

  17. s "abc" "abc" "abc" x s t t Viite metodin paluuarvona public class ViitePaluuarvona { /* Palautetaan viite luotuun merkkijono-olioon. */ public static String palauta() { String s = new String("abc"); return s; } public static void main(String[] args) { // Olio säilyy metodista poistuttaessa, // koska olioon liitetään uusi viite t. String t = palauta(); System.out.println(t); // abc } }

  18. Viite metodin parametrina • Viitetyyppisiä muuttujia voidaan antaa metodeille parametriksi aivan kuten alkeistyyppisiä muuttujia. • Esim. int kertoma(int luku) { ... } void nimi(String nimi) { ... } double keskiarvo(double[] luvut) { ... } • Java sijoittaa sekä alkeis- että viitetyyppisen parametrin arvoksi alkuperäisen arvon kopion (pass-by-value). • Parametrin arvoon metodissa tehty muutos katoaa, kun metodista poistutaan.

  19. a x x Ennen tai jälkeen metodi-kutsun A x = new A(); m(x); void m(A y) { ... } Metodissa y a Viite metodin parametrina • Viitetyyppiseen parametriin liittyvään olioon metodissa tehty muutos jää voimaan! • Olio ei kopioidu, jolloin viitetyyppinen parametri viittaa samaan olioon kuin metodikutsussa annettu viite. • Olkoon x viite luokan A olioon a ja mvoid-tyyppinen metodi, jolla on A-tyyppinen parametri y.

  20. Viite metodin parametrina public class ParametriTesti { /* Annetaan alkeistyyppiselle parametrille uusi arvo. */ public static void korota2Potenssiin(int p) { p = p * p; } /* Annetaan viitetyyppiselle parametrille uusi arvo. */ public static void luoMaatiainen(Kissa k) { k = new Kissa("kirjava", "tavallinen"); } /* Muutetaan olion tietoja. */ public static void leikita(Kissa k) { if (k != null) k.hanta("levoton"); }

  21. Viite metodin parametrina public static void main(String[] args) { // Yritetään muuttaa alkeistyyppisen muuttujan arvoa. int luku = 4; korota2Potenssiin(luku); System.out.println(luku); // 4 // Yritetään muuttaa viitetyyppisen muuttujan arvoa. Kissa katti = new Kissa(); // musta, kippura luoMaatiainen(katti); System.out.println(katti.vari()); // musta System.out.println(katti.hanta()); // kippura // Muutetaan olion tietoja. leikita(katti); System.out.println(katti.vari()); // musta System.out.println(katti.hanta()); // levoton } }

  22. public class MerkkijonoParametrina { /* Olion tiedot muuttuvat. */ public static void muuta(StringBuffer s) { s.append("d"); } /* Olion tiedot eivät muutu. */ public static void muuta(String s) { s = s + "d"; } public static void main(String[] args) { StringBuffer sb = new StringBuffer("abc"); String s = new String("abc"); muuta(sb); System.out.println(sb); // abcd muuta(s); System.out.println(s); // abc } } String-luokka on toteutettu siten, että String-tyyppisten muuttujien tietoihin ei voida tehdä muutoksia. Muutetun merkkijonon palauttaminen onnistuu paluuarvona tai StringBuffer- ja StringBuilder-luokkia käyttäen. Viite metodin parametrina

More Related