Ohjelmointi

Objektit ja taulukot

Tervetuloa toiseen Konepellin alle. Tämä sarake keskittyy Java-tekniikoihin. Sen tarkoituksena on antaa kehittäjille vilauksen mekanismeista, jotka saavat Java-ohjelmansa toimimaan. Tämän kuukauden artikkelissa tarkastellaan tavuja ja taulukoita käsitteleviä tavukoodeja.

Kohdesuuntainen kone

Java-virtuaalikone (JVM) toimii tietojen kanssa kolmessa muodossa: objektit, objektiviitteet ja primitiiviset tyypit. Esineet sijaitsevat roskakorilla. Objektiviitteet ja primitiiviset tyypit sijaitsevat joko Java-pinossa paikallisin muuttujina, kasassa esineiden muuttujina tai metodialueella luokan muuttujina.

Java-virtuaalikoneessa muisti varataan roskakoriin vain esineinä. Kasan primitiiviselle tyypille ei ole mahdollista kohdistaa muistia, paitsi osana kohdetta. Jos haluat käyttää primitiivistä tyyppiä, jossa Esine tarvitaan viite, voit määrittää tyypille kääreobjektin java.lang paketti. Esimerkiksi on Kokonaisluku luokka, joka kääri int kirjoita objektilla. Vain objektiviitteet ja primitiiviset tyypit voivat asua Java-pinoa paikallisena muuttujana. Objektit eivät voi koskaan sijaita Java-pinossa.

Kohteiden ja primitiivisten tyyppien arkkitehtoninen erottelu JVM: ssä heijastuu Java-ohjelmointikielessä, jossa objekteja ei voida ilmoittaa paikallisina muuttujina. Vain objektiviitteet voidaan julistaa sellaisiksi. Ilmoituksessa objektiviite ei viittaa mihinkään. Vasta sen jälkeen, kun viite on nimenomaisesti alustettu - joko viittauksella olemassa olevaan objektiin tai kutsulla Uusi - viittaako viittaus varsinaiseen esineeseen.

JVM-käskysarjassa kaikki objektit instantisoidaan ja niihin pääsee käsiksi samalla joukolla opkoodeja, matriiseja lukuun ottamatta. Java-taulukot ovat täysimittaisia ​​objekteja, ja kuten kaikki muut Java-ohjelman objektit, ne luodaan dynaamisesti. Matriisiviittauksia voidaan käyttää missä tahansa tyypin viitteessä Esine vaaditaan ja mikä tahansa menetelmä Esine voidaan käyttää taulukossa. Java-virtuaalikoneessa matriiseja kuitenkin käsitellään erityisillä tavukoodeilla.

Kuten minkä tahansa muun objektin kohdalla, matriiseja ei voida ilmoittaa paikallisina muuttujina; vain matriisiviitteet voivat. Matriisikohteet itse sisältävät aina joko primitiivisten tyyppien ryhmän tai joukon objektiviittauksia. Jos ilmoitat joukon objekteja, saat joukon objektiviittauksia. Kohteet itse on luotava nimenomaisesti Uusi ja osoitettu taulukon elementeille.

Objektien opkoodit

Uusien kohteiden välitön välitys tapahtuu

Uusi

opkoodi. Kaksi yksitavuista operandia seuraa

Uusi

opkoodi. Nämä kaksi tavua yhdistetään muodostamaan 16-bittinen indeksi vakiopooliin. Määritetyn siirtymän vakio-allaselementti antaa tietoa uuden objektin luokasta. JVM luo kasaan uuden objektin ilmentymän ja työntää viitteen uuteen kohteeseen pinoon alla olevan kuvan mukaisesti.

Kohteen luominen
OpcodeOperandi (t)Kuvaus
Uusiindexbyte1, indexbyte2luo uuden objektin kasaan, työntää viitteitä

Seuraava taulukko näyttää opkoodit, jotka laittaa ja haevat objektikenttiä. Nämä opkoodit, putfield ja getfield, toimivat vain kentissä, jotka ovat instanssimuuttujia. Staattisiin muuttujiin pääsee putstaticilla ja getstaticilla, jotka kuvataan myöhemmin. Putfield- ja getfield-ohjeet vievät molemmat kaksi yksitavuista operandia. Operandit yhdistetään muodostamaan 16-bittinen indeksi vakiopooliin. Kyseisen hakemiston vakiopoolikohta sisältää tietoja kentän tyypistä, koosta ja siirtymästä. Objektiviite otetaan pinosta sekä putfield- että getfield-ohjeissa. Putfield-käsky ottaa ilmentymämuuttujan arvon pinosta, ja getfield-käsky työntää haetun ilmentymämuuttujan arvon pinoon.

Käytetään ilmentymämuuttujia
OpcodeOperandi (t)Kuvaus
putfieldindexbyte1, indexbyte2aseta kenttä, osoitettu indeksillä, objektista arvoon (molemmat otetaan pinosta)
getfieldindexbyte1, indexbyte2työntää objektin kentän, joka on merkitty indeksillä (otettu pinosta)

Luokkamuuttujiin pääsee getstatic- ja putstatic-opkodeilla, kuten alla olevassa taulukossa on esitetty. Sekä getstatic että putstatic ottavat kaksi yksitavuista operandia, jotka JVM yhdistää muodostaen 16-bittisen allekirjoittamattoman siirtymän vakiopooliin. Vakio poolikohta kyseisessä paikassa antaa tietoja yhdestä luokan staattisesta kentästä. Koska staattiseen kenttään ei ole liitetty tiettyä objektia, ei ole getstatic- tai putstatic-objektin käyttämää objektiviitettä. Putstatinen käsky vie arvon pinolle. Getstatic-käsky työntää haetun arvon pinoon.

Luokkimuuttujien käyttö
OpcodeOperandi (t)Kuvaus
putstaattinenindexbyte1, indexbyte2aseta kenttä, osoitettu indeksillä, objektista arvoon (molemmat otetaan pinosta)
staattinenindexbyte1, indexbyte2työntää objektin kentän, joka on merkitty indeksillä (otettu pinosta)

Seuraavat opkoodit tarkistavat, viittaako pinon päällä oleva objektiviittaus luokan tai rajapinnan esiintymään, jonka operandit ovat indeksoineet opkoodin jälkeen. Checkcast-ohje heittää CheckCastException jos objekti ei ole määritetyn luokan tai rajapinnan esiintymä. Muuten checkcast ei tee mitään. Objektiviite pysyy pinossa ja suorittamista jatketaan seuraavalla käskyllä. Tämä ohje varmistaa, että heitot ovat turvallisia ajoaikana ja muodostavat osan JVM: n suojapeitteestä.

Käskyn instanssi ponnahtaa objektiviittauksen pinon yläosasta ja työntää tosi tai epätosi. Jos esine on todellakin määritetyn luokan tai rajapinnan esiintymä, tosi työnnetään pinolle, muuten epätosi työnnetään pinolle. Käskyn instanssia käytetään esiintymä Java-avainsana, jonka avulla ohjelmoijat voivat testata, onko esine tietyn luokan tai käyttöliittymän esiintymä.

Tyyppitarkistus
OpcodeOperandi (t)Kuvaus
tarkistuslähetysindexbyte1, indexbyte2Heittää ClassCastException-toiminnon, jos pinon objektiviitettä ei voida heittää luokkaan hakemistossa
esiintymäindexbyte1, indexbyte2Työnnä tosi, jos pinon objektiref on hakemiston luokan esimerkki, muuten väärä

Matriisien opkoodit

Uusien matriisien välitön välitys tapahtuu uudella, uudella ja usean ytimen opkodeilla. Newarray-opkoodia käytetään muiden primitiivisten tyyppien taulukoiden kuin objektiviittausten luomiseen. Erityisen primitiivisen tyypin määrittelee yksi yksitavuinen operandi, joka seuraa newarray-opkoodia. Newarray-käsky voi luoda taulukoita tavulle, lyhyelle, charille, intille, pitkälle, kelluvalle, kaksinkertaiselle tai loogiselle.

Anewarray-käsky luo joukon objektiviittauksia. Kaksi yksitavuista operandia seuraavat uudelleenkäynnistyskoodia ja yhdistetään muodostamaan 16-bittinen hakemisto vakiopooliin. Kuvaus objektiluokasta, jolle taulukko luodaan, löytyy vakiopoolista määritetyssä hakemistossa. Tämä käsky varaa tilaa objektiviittausten ryhmälle ja alustaa viittaukset nollaan.

Moniulostuskäskyä käytetään allokoimaan moniulotteisia taulukoita - jotka ovat yksinkertaisesti matriisiryhmiä - ja ne voidaan allokoida toistamalla ennakko- ja uudelleenkäskyjä. Moniulotteinen käsky yksinkertaisesti pakkaa moniulotteisten taulukoiden luomiseen tarvittavat tavukoodit yhdeksi käskyksi. Kaksi yksitavuista operandia seuraa moniulotteista opkoodia ja yhdistetään muodostamaan 16-bittinen hakemisto vakiopooliin. Kuvaus objektiluokasta, jolle taulukko luodaan, löytyy vakiopoolista määritetyssä hakemistossa. Välittömästi kahden vakiotyyppisen indeksin muodostavan yksitavuisen operandin seuraaminen on yksitavuinen operandi, joka määrittää tämän moniulotteisen taulukon ulottuvuuksien määrän. Kunkin ulottuvuuden koot ponnahtaa pois pinosta. Tämä ohje jakaa tilaa kaikille matriiseille, joita tarvitaan moniulotteisten taulukoiden toteuttamiseen.

Uusien taulukoiden luominen
OpcodeOperandi (t)Kuvaus
newarraytyyppiponnahtaa pituuden, allokoi uuden tyyppisen primitiivisen tyypin, jonka atype osoittaa, työntää uuden taulukon objektireffin
uudestaanindexbyte1, indexbyte2ponnahtaa pituuden, allokoi uuden ryhmän objektit, jotka on merkitty indexbyte1 ja indexbyte2, työntää uuden taulukon objectref
moniulotteinenindexbyte1, indexbyte2, mitatponnahtaa matriisin matriisipituuksien lukumäärän, allokoi uuden luokan moniulotteisen taulukon, jonka osoittavat indexbyte1 ja indexbyte2, työntää uuden taulukon

Seuraava taulukko näyttää ohjeet, jotka pudottavat matriisin viitteen pois pinon yläosasta ja työntävät kyseisen matriisin pituuden.

Matriisin pituuden saaminen
OpcodeOperandi (t)Kuvaus
taulukon pituus(ei mitään)ponnahtaa taulukon objektireffin, työntää matriisin pituuden

Seuraavat opkoodit noutavat elementin taulukosta. Taulukkoindeksi ja taulukon viite ponnahtaa pinosta, ja määritetyn taulukon määritetyn hakemiston arvo työnnetään takaisin pinoon.

Haetaan taulukkoelementti
OpcodeOperandi (t)Kuvaus
baload(ei mitään)ponnahtaa tavujärjestelmän hakemiston ja taulukon, työntää taulukon taulukon [hakemisto]
caload(ei mitään)ponnahtaa hakemistomerkin hakemiston ja taulukon, työntää arrayref [hakemisto]
saload(ei mitään)ponnahtaa shortsiryhmän hakemiston ja taulukon, työntää arrayref [hakemisto]
iaload(ei mitään)ponnahtaa hakemiston ja taulukon taulukon taulukon, työntää arrayref [hakemisto]
laload(ei mitään)ponnahtaa pitkän matriisin hakemiston ja taulukon, työntää arrayref [hakemisto]
faload(ei mitään)ponnahtaa float-ryhmän hakemiston ja taulukon, työntää arrayref [hakemisto]
daload(ei mitään)ponnahtaa hakemiston ja taulukon taulukon taulukon, työntää arrayref [hakemisto]
aaload(ei mitään)ponnahtaa hakemiston ja taulukon taulukon taulukon taulukon, työntää taulukon taulukon [hakemisto]

Seuraava taulukko näyttää opkoodit, jotka tallentavat arvon taulukkoelementtiin. Arvo, hakemisto ja taulukon viite ponnahtaa pinon yläosasta.

Tallentaminen taulukkoelementtiin
OpcodeOperandi (t)Kuvaus
bastore(ei mitään)ponnahtaa tavujoukon arvon, hakemiston ja taulukon taulukon, määrittää arrayref [indeksi] = arvo
castore(ei mitään)ponnahtaa merkkiryhmän arvon, hakemiston ja taulukon taulukon, määrittää arrayref [indeksi] = arvo
sastore(ei mitään)ponnahtaa shortsiryhmän arvon, indeksin ja taulukonrefin, määrittää arrayref [indeksi] = arvo
iastore(ei mitään)ponnahtaa esiin joukon inttejä, hakemistoja ja taulukoita, määrittää arrayref [indeksi] = arvo
lastore(ei mitään)ponnahtaa pitkien matriisien arvon, indeksin ja taulukon, antaa matriisiref [indeksi] = arvo
Fastore(ei mitään)ponnahtaa kelluvien matriisien arvon, indeksin ja arrayref: n, määrittää arrayref [index] = arvon
dastore(ei mitään)ponnahtaa kaksinkertaisen matriisin arvon, indeksin ja taulukon, antaa arrayref [indeksi] = arvo
aastore(ei mitään)ponnahtaa objectrefs-taulukon arvon, indeksin ja arrayref-arvon, antaa arrayref-indeksin [index] = arvo

Kolmiulotteinen taulukko: Java-virtuaalikoneen simulointi

Alla oleva sovelma osoittaa Java-virtuaalikoneen suorittavan tavujärjestyssarjan. Simulaation tavukoodisekvenssi luotiin javac varten initAnArray () alla olevan luokan menetelmä:

class ArrayDemo {staattinen void initAnArray () {int [] [] [] threeD = uusi int [5] [4] [3]; for (int i = 0; i <5; ++ i) {for (int j = 0; j <4; ++ j) {varten (int k = 0; k <3; ++ k) {kolme i] [j] [k] = i + j + k; }}}}} 

Luodut tavukoodit javac varten initAnArray () ovat alla:

$config[zx-auto] not found$config[zx-overlay] not found