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.
Opcode | Operands (-i) | Apraksts |
---|
jauns | indexbyte1, indexbyte2 | izveido 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
Opcode | Operands (-i) | Apraksts |
---|
putfīlds | indexbyte1, indexbyte2 | iestatītais objekta un vērtības lauks, kas norādīts ar indeksu (abi ņemti no kaudzes) |
getfield | indexbyte1, indexbyte2 | nospiež 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
Opcode | Operands (-i) | Apraksts |
---|
putstatisks | indexbyte1, indexbyte2 | iestatītais objekta un vērtības lauks, kas norādīts ar indeksu (abi ņemti no kaudzes) |
getstatic | indexbyte1, indexbyte2 | nospiež 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.
Opcode | Operands (-i) | Apraksts |
---|
čeka raidījums | indexbyte1, indexbyte2 | Izmet ClassCastException, ja objekta norādi uz kaudzes nevar nodot klasē indeksā |
instanceof | indexbyte1, indexbyte2 | Spiež 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.
Opcode | Operands (-i) | Apraksts |
---|
newarray | tips | uznirst garums, piešķir jaunu primitīvu tipu masīvu, kas norādīts ar atipu, nospiež jaunā masīva objectref |
no jauna | indexbyte1, indexbyte2 | uznirst garums, piešķir jaunu klases objektu masīvu, ko norāda indexbyte1 un indexbyte2, nospiež jaunā masīva objectref |
daudzkārtējs | indexbyte1, indexbyte2, izmēri | izš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.
Opcode | Operands (-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
Opcode | Operands (-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
Opcode | Operands (-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: