Programmēšana

Objekti un masīvi

Laipni lūdzam citā Zem kapuces. Šajā slejā galvenā uzmanība tiek pievērsta Java pamatā esošajām tehnoloģijām. Tās mērķis ir dot izstrādātājiem ieskatu mehānismos, kas liek darboties viņu Java programmām. Šī mēneša rakstā tiek apskatīti baitkodi, kas attiecas uz objektiem un masīviem.

Uz objektu orientēta mašīna

Java virtuālā mašīna (JVM) ar datiem darbojas trīs formās: objekti, objektu atsauces un primitīvie veidi. Objekti atrodas uz atkritumu savāktās kaudzes. Objekta atsauces un primitīvie veidi atrodas vai nu Java kaudzē kā lokālie mainīgie, kaudzē kā objektu mainīgie lielumi, vai metodes apgabalā kā klases mainīgie.

Java virtuālajā mašīnā atmiņa uz atkritumu savākto kaudzi tiek piešķirta tikai kā objekti. Nav iespējams piešķirt atmiņu primitīvam tipam uz kaudzes, izņemot objekta daļu. Ja vēlaties izmantot primitīvu tipu, kur Objekts ir nepieciešama atsauce, jūs varat piešķirt iesaiņojuma objektu tipam no java.lang iepakojums. Piemēram, ir Vesels skaitlis klase, kas ietin an int ierakstiet ar objektu. Java objektā kā lokālie mainīgie var atrasties tikai objektu atsauces un primitīvi tipi. Objekti nekad nevar atrasties Java kaudzē.

Objektu un primitīvo tipu arhitektoniskā nošķiršana JVM tiek atspoguļota Java programmēšanas valodā, kurā objektus nevar deklarēt kā lokālos mainīgos. Par tādām var deklarēt tikai atsauces uz objektiem. Pēc deklarēšanas objekta atsauce neattiecas uz neko. Tikai pēc tam, kad atsauce ir skaidri inicializēta - vai nu ar atsauci uz esošu objektu, vai ar aicinājumu uz jauns - vai atsauce attiecas uz faktisko objektu.

JVM instrukciju komplektā visi objekti tiek instantificēti un tiem piekļūst, izmantojot vienādu opkodu kopu, izņemot masīvus. Java masīvi ir pilnvērtīgi objekti, un, tāpat kā visi citi Java programmas objekti, tie tiek veidoti dinamiski. Masīva atsauces var izmantot visur, kur ir atsauce uz tipu Objekts tiek pieprasīta jebkura metode Objekts var izmantot masīvā. Tomēr Java virtuālajā mašīnā masīvi tiek apstrādāti ar īpašiem baitkodiem.

Tāpat kā jebkuru citu objektu, masīvus nevar deklarēt kā lokālos mainīgos; var tikai masīva atsauces. Masīvu objekti vienmēr satur vai nu primitīvu tipu masīvu, vai arī objektu atsauču masīvu. Deklarējot objektu masīvu, jūs saņemat objektu masīvu masīvu. Paši objekti ir skaidri jāizveido ar jauns un piešķirts masīva elementiem.

Objektu opkodi

Jaunu objektu izstādīšana tiek veikta, izmantojot

jauns

opkods. Divi viena baita operandi seko

jauns

opkods. Šie divi baiti ir apvienoti, lai izveidotu 16 bitu indeksu nemainīgajā baseinā. Konstantā kopas elements norādītajā nobīdē sniedz informāciju par jaunā objekta klasi. JVM izveido jaunu objekta eksemplāru uz kaudzes un nospiež kaudzē atsauci uz jauno objektu, kā parādīts zemāk.

Objekta izveidošana
OpcodeOperands (-i)Apraksts
jaunsindexbyte1, indexbyte2izveido jaunu objektu uz kaudzes, nospiež atsauci

Nākamajā tabulā parādīti opkodi, kas ievieto un iegūst objektu laukus. Šie opkodi, putfield un getfield, darbojas tikai laukos, kas ir instances mainīgie. Statiskajiem mainīgajiem var piekļūt putstatic un getstatic, kas aprakstīti vēlāk. Putfīlda un getfīlda instrukcijās katrs paņem divus viena baita operandus. Operandi tiek apvienoti, lai izveidotu 16 bitu indeksu nemainīgajā baseinā. Pastāvīgais kopas elements šajā indeksā satur informāciju par lauka tipu, lielumu un nobīdi. Objekta atsauce tiek ņemta no kaudzes gan putfield, gan getfield instrukcijās. Putfield instrukcija ņem eksemplāra mainīgā vērtību no kaudzes, un getfield instrukcija izgūst iegūtās instances mainīgā vērtību kaudzē.

Piekļuve instances mainīgajiem
OpcodeOperands (-i)Apraksts
putfīldsindexbyte1, indexbyte2iestatītais objekta un vērtības lauks, kas norādīts ar indeksu (abi ņemti no kaudzes)
getfieldindexbyte1, indexbyte2nospiež objekta lauku, kas norādīts ar indeksu (ņemts no kaudzes)

Klases mainīgajiem var piekļūt, izmantojot getstatic un putstatic opcodes, kā parādīts zemāk esošajā tabulā. Gan getstatic, gan putstatic ņem divus viena baita operandus, kurus JVM apvieno, veidojot 16 bitu neparakstītu nobīdi nemainīgajā baseinā. Pastāvīgais baseina elements šajā vietā sniedz informāciju par vienu klases statisko lauku. Tā kā nav noteikta objekta, kas saistīts ar statisko lauku, nav objekta atsauces, ko izmantotu vai nu getstatic, vai putstatic. Putstatiskā instrukcija ņem vērtību, ko piešķirt no kaudzes. Getstatic instrukcija izgūst iegūto vērtību kaudzē.

Piekļuve klases mainīgajiem
OpcodeOperands (-i)Apraksts
putstatisksindexbyte1, indexbyte2iestatītais objekta un vērtības lauks, kas norādīts ar indeksu (abi ņemti no kaudzes)
getstaticindexbyte1, indexbyte2nospiež objekta lauku, kas norādīts ar indeksu (ņemts no kaudzes)

Šie opkodi pārbauda, ​​vai objekta atsauce kaudzes augšpusē attiecas uz klases vai saskarnes gadījumu, kuru indeksē operandi, kas seko opkodam. Checkcast instrukcija met CheckCastException ja objekts nav norādītās klases vai saskarnes gadījums. Pretējā gadījumā checkcast nedara neko. Objekta atsauce paliek uz kaudzes, un izpilde tiek turpināta nākamajā instrukcijā. Šī instrukcija nodrošina, ka pārraides ir drošas izpildes laikā un ir daļa no JVM drošības segas.

Instrukcijas instanceof izvelk objekta atsauci no kaudzes augšdaļas un nospiež patiesu vai nepatiesu. Ja objekts patiešām ir norādītās klases vai saskarnes gadījums, tad taisnība tiek virzīta uz kaudzi, pretējā gadījumā nepatiesa tiek virzīta uz kaudzīti. Instrukcijas instanceof tiek izmantots, lai ieviestu instanceof Java atslēgvārds, kas ļauj programmētājiem pārbaudīt, vai objekts ir noteiktas klases vai saskarnes gadījums.

Tipa pārbaude
OpcodeOperands (-i)Apraksts
čeka raidījumsindexbyte1, indexbyte2Izmet ClassCastException, ja objekta norādi uz kaudzes nevar nodot klasē indeksā
instanceofindexbyte1, indexbyte2Spiež taisnību, ja kaudzē objectref indeksā ir klases instance, citādi - nepatiesa

Masīvu opkodi

Jaunu masīvu instancēšana tiek veikta, izmantojot newarray, anewarray un multianewray opcodes. Newarray opkods tiek izmantots, lai izveidotu primitīvu tipu masīvus, izņemot objektu atsauces. Konkrēto primitīvo tipu nosaka viens vienbaits operands, kas seko newarray opkodam. Newarray instrukcija var izveidot masīvus baitam, short, char, int, long, float, double vai boolean.

Anewarray instrukcija izveido objektu atsauču masīvu. Divi viena baita operandi seko iepriekšējam opkodam un tiek apvienoti, lai izveidotu 16 bitu indeksu nemainīgajā baseinā. Objekta klases, kurai jāizveido masīvs, apraksts ir atrodams nemainīgā pūlā pie norādītā indeksa. Šī instrukcija piešķir vietu objektu atsauču masīvam un inicializē atsauces uz null.

Daudzlīmeņu instrukciju izmanto, lai piešķirtu daudzdimensionālus masīvus - kas ir vienkārši masīvu masīvi - un tos varētu piešķirt, atkārtoti izmantojot priekšplānojuma un jaunizveidotās instrukcijas. Daudzlīmeņu instrukcija vienkārši saspiež daudzdimensionālo masīvu izveidošanai nepieciešamos baitkodus vienā instrukcijā. Divi viena baita operandi seko daudzjoslu opkodam un tiek apvienoti, veidojot 16 bitu indeksu nemainīgajā baseinā. Objekta klases, kurai jāizveido masīvs, apraksts ir atrodams nemainīgā pūlā pie norādītā indeksa. Tūlīt pēc diviem viena baita operandiem, kas veido nemainīgu kopas indeksu, ir viena baita operands, kas norāda dimensiju skaitu šajā daudzdimensionālajā masīvā. Katras dimensijas izmēri tiek izlaisti no kaudzes. Šī instrukcija piešķir vietu visiem masīviem, kas nepieciešami daudzdimensionālo masīvu ieviešanai.

Jaunu masīvu izveide
OpcodeOperands (-i)Apraksts
newarraytipsuznirst garums, piešķir jaunu primitīvu tipu masīvu, kas norādīts ar atipu, nospiež jaunā masīva objectref
no jaunaindexbyte1, indexbyte2uznirst garums, piešķir jaunu klases objektu masīvu, ko norāda indexbyte1 un indexbyte2, nospiež jaunā masīva objectref
daudzkārtējsindexbyte1, indexbyte2, izmēriizšauj dimensijas masīva garumu skaitu, piešķir jaunu daudzdimensionālu klases masīvu, ko norāda indexbyte1 un indexbyte2, nospiež jaunā masīva objectref

Nākamajā tabulā ir parādīta instrukcija, kas noliek masīva atsauci pie kaudzes augšdaļas un nospiež šī masīva garumu.

Masīva garuma iegūšana
OpcodeOperands (-i)Apraksts
masīva garums(nav)pops masīva objectref, nospiež šī masīva garumu

Šie opcodes izgūst elementu no masīva. Masīva indekss un masīva atsauce tiek parādīta no kaudzes, un vērtība pie norādītā masīva norādītā indeksa tiek virzīta atpakaļ uz kaudzīti.

Notiek masīva elementa izguve
OpcodeOperands (-i)Apraksts
baload(nav)pops baitu masīva indekss un masīvsrefs, nospiež arrayref [rādītājs]
caload(nav)izlec simbolu masīva indeksu un masīvrefu, nospiež arrayref [rādītājs]
saload(nav)pops indekss un masīvs šorti masīvs, nospiež arrayref [rādītājs]
iaload(nav)izlec intu masīva indeksu un masīvrefu, nospiež arrayref [rādītājs]
laload(nav)izlec garu masīva indeksu un masīva atsauci, nospiež arrayref [rādītājs]
faload(nav)uzrāda pludiņu masīva indeksu un masīvu atsauci, nospiež arrayref [rādītājs]
daload(nav)pops indekss un masīvu divvietīgo masīvs, nospiež arrayref [rādītājs]
aaload(nav)pops indeksu un arrayref masīvs objectrefs, nospiež arrayref [indekss]

Nākamajā tabulā parādīti opkodi, kas vērtību saglabā masīva elementā. Vērtība, indekss un masīva atsauce tiek parādīta no kaudzes augšdaļas.

Saglabāšana pie masīva elementa
OpcodeOperands (-i)Apraksts
Bastore(nav)uzrāda baitu masīva vērtību, indeksu un masīvu atsauci, piešķir arrayref [indekss] = vērtība
castore(nav)izlec rakstzīmju masīva vērtību, indeksu un masīvu ref, piešķir arrayref [indekss] = vērtība
sastore(nav)izšauj šortu masīva vērtību, indeksu un masīvu atsauci, piešķir masīvu ref [indekss] = vērtība
iastore(nav)pops masīvu intu vērtība, indekss un masīvsref, piešķir arrayref [indekss] = vērtība
pēdējais(nav)izlec garumu masīva vērtību, indeksu un masīva refu, piešķir masīvu ref [indekss] = vērtība
fastore(nav)pops masīva pops vērtība, indekss un masīvsref, piešķir arrayref [indekss] = vērtība
dastore(nav)pops masīvu dubultspēļu vērtība, indekss un masīvsref, piešķir arrayref [indekss] = vērtība
aastore(nav)izvelk objectrefs masīva vērtību, indeksu un arrayref, piešķir arrayref [index] = vērtība

Trīsdimensiju masīvs: Java virtuālās mašīnas simulācija

Zemāk esošā sīklietotne parāda Java virtuālo mašīnu, kas izpilda baitkodu secību. Baitkodu secību simulācijā ģenerēja javac priekš initAnArray () zemāk redzamās klases metode:

klase ArrayDemo {static void initAnArray () {int [] [] [] threeD = jauns int [5] [4] [3]; par (int i = 0; i <5; ++ i) {par (int j = 0; j <4; ++ j) {par (int k = 0; k <3; ++ k) {trīsD [ i] [j] [k] = i + j + k; }}}}} 

Bytecodes, ko ģenerējis javac priekš initAnArray () ir parādīti zemāk:

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