Programovanie

Životný štýl súborov triedy Java

Vitajte v ďalšom pokračovaní filmu „Pod kapotou“. V minulomesačnom článku som diskutoval o Java Virtual Machine alebo JVM, abstraktnom počítači, pre ktorý sú kompilované všetky programy Java. Ak nie ste oboznámení s JVM, možno by ste si mali prečítať článok z minulého mesiaca pred týmto. V tomto článku ponúkam letmý pohľad na základnú štruktúru a životný štýl súboru triedy Java.

Narodený na cestovanie

Súbor triedy Java je presne definovaný formát pre kompilovanú Javu. Zdrojový kód Java je kompilovaný do súborov triedy, ktoré môžu byť načítané a vykonávané ľubovoľným JVM. Súbory triedy môžu pred načítaním JVM cestovať po sieti.

V skutočnosti, ak čítate tento článok prostredníctvom prehľadávača podporujúceho technológiu Java, súbory triedy pre simulačný applet na konci článku práve teraz lietajú cez internet do vášho počítača. Ak ich chcete počúvať (a váš počítač má zvukové možnosti), stlačte nasledujúce tlačidlo:

Na prezeranie tohto appletu potrebujete prehliadač s podporou Java

Znie to, akoby sa bavili, hm? Je to v ich povahe. Súbory triedy Java boli navrhnuté tak, aby sa im dobre cestovalo. Sú nezávislé na platforme, takže budú vítaní na viacerých miestach. Obsahujú bytecodes, kompaktnú inštrukčnú sadu pre JVM, takže môžu cestovať naľahko. Súbory triedy Java neustále prechádzajú sieťami závratnou rýchlosťou, aby sa dostali k súborom JVM po celom svete.

Čo je v spise triedy?

Súbor triedy Java obsahuje všetko, čo JVM potrebuje vedieť o jednej triede alebo rozhraní Java. V poradí, v akom sa nachádzajú v súbore triedy, sú hlavné komponenty: mágia, verzia, konštantná skupina, príznaky prístupu, táto trieda, super trieda, rozhrania, polia, metódy a atribúty.

Informácie uložené v súbore triedy majú často rôznu dĺžku - to znamená, že skutočnú dĺžku informácií nie je možné predvídať pred načítaním súboru triedy. Napríklad počet metód uvedených v komponente methods sa môže medzi súbormi tried líšiť, pretože závisí od počtu metód definovaných v zdrojovom kóde. Tieto informácie sú usporiadané v súbore triedy podľa skutočnej informácie pred jej veľkosťou alebo dĺžkou. Týmto spôsobom, keď sa trieda načítava JVM, najskôr sa načíta veľkosť informácií o premennej dĺžke. Len čo JVM pozná veľkosť, môže správne načítať skutočné informácie.

Informácie sa zvyčajne zapisujú do súboru triedy bez medzery alebo polstrovania medzi nasledujúcimi informáciami; všetko je zarovnané na hraniciach bajtov. To pomáha udržiavať súbory triedy drobné, takže pri prelete v sieťach budú aerodynamické.

Poradie komponentov súboru triedy je prísne definované, takže JVM môžu pri načítaní súboru triedy vedieť, čo môžu očakávať a kde to môžu očakávať. Napríklad každý JVM vie, že prvých osem bajtov súboru triedy obsahuje čísla mágie a verzie, že konštantná oblasť začína na deviatom bajte a že príznaky prístupu nasledujú po konštantnej oblasti. Ale pretože konštantná oblasť má premenlivú dĺžku, nevie presné miesto, kde sa nachádzajú príznaky prístupu, kým nedokončí čítanie v konštantnej oblasti. Po dokončení čítania v konštantnej oblasti vie, že ďalšie dva bajty budú prístupové príznaky.

Kúzla a čísla verzií

Prvé štyri bajty každého súboru triedy sú vždy 0xCAFEBABE. Toto magické číslo umožňuje ľahšiu identifikáciu súborov triedy Java, pretože je malá šanca, že súbory bez triedy by začali rovnakými počiatočnými štyrmi bajtmi. Toto číslo sa nazýva magické, pretože ho návrhári formátov súborov môžu vytiahnuť z klobúka. Jedinou požiadavkou je, aby ho už nepoužíval iný formát súboru, s akým sa v reálnom svete môže stretnúť. Podľa Patricka Naughtona, kľúčového člena pôvodného tímu Java, bolo magické číslo zvolené „dávno predtým, ako sa v súvislosti s týmto jazykom niekedy vyslovil názov Java. Hľadali sme niečo zábavné, jedinečné a ľahko zapamätateľné. len zhoda okolností, že OxCAFEBABE, šikmý odkaz na roztomilých baristov v spoločnosti Peet's Coffee, bol predzvesťou názvu Java. “

Druhé štyri bajty súboru triedy obsahujú čísla hlavnej a vedľajšej verzie. Tieto čísla identifikujú verziu formátu súboru triedy, ktorej sa konkrétny súbor triedy drží, a umožňujú JVM overiť, či je súbor triedy možné načítať. Každý JVM má maximálnu verziu, ktorú je možné načítať, a JVM odmietne súbory triedy s novšími verziami.

Konštantný bazén

Súbor triedy ukladá konštanty spojené s jeho triedou alebo rozhraním v skupine konštánt. Niektoré konštanty, ktoré sa môžu vo fólii pohybovať, sú literálne reťazce, konečné hodnoty premenných, názvy tried, názvy rozhraní, názvy a typy premenných a názvy metód a podpisy. Metóda podpis je jeho návratový typ a množina typov argumentov.

Konštantná skupina je organizovaná ako pole prvkov s premennou dĺžkou. Každá konštanta zaberá jeden prvok v poli. V celom súbore triedy sa na konštanty odkazuje celočíselný index, ktorý označuje ich pozíciu v poli. Počiatočná konštanta má index jeden, druhá konštanta má index dva atď. Pole konštantných poolov predchádza veľkosť poľa, takže JVM budú vedieť, koľko konštánt možno očakávať pri načítaní súboru triedy.

Každý prvok skupiny konštánt začína jednobajtovou značkou určujúcou typ konštanty na tejto pozícii v poli. Len čo JVM túto značku uchopí a interpretuje, vie, čo po značke nasleduje. Napríklad, ak značka označuje, že konštanta je reťazec, JVM očakáva, že ďalšie dva bajty budú mať dĺžku reťazca. Po tejto dvojbytovej dĺžke očakáva JVM nájdenie dĺžka počet bajtov, ktoré tvoria znaky reťazca.

Vo zvyšku článku budem niekedy označovať n-tý prvok poľa konštantných bazénov ako constant_pool [n]. To dáva zmysel do tej miery, že konštantná skupina je organizovaná ako pole, ale treba mať na pamäti, že tieto prvky majú rôzne veľkosti a typy a že prvý prvok má index jednej.

Príznaky prístupu

Prvé dva bajty za konštantnou oblasťou, príznaky prístupu, označujú, či tento súbor definuje triedu alebo rozhranie, či je trieda alebo rozhranie verejné alebo abstraktné, a (ak ide o triedu a nie rozhranie), či je alebo nie je trieda je konečné.

Táto trieda

Ďalšie dva bajty, tejto triedy komponent, sú indexom do poľa konštantných poolov. Konštanta, na ktorú odkazuje tejto triedy, constant_pool [this_class], má dve časti, jednobajtovú značku a dvojbajtový index mien. Značka sa bude rovnať CONSTANT_Class, hodnota, ktorá označuje, že tento prvok obsahuje informácie o triede alebo rozhraní. Constant_pool [name_index] je reťazcová konštanta obsahujúca názov triedy alebo rozhrania.

The tejto triedy komponent poskytuje pohľad na to, ako sa používa konštantná skupina. Táto trieda sám o sebe je iba indexom do konštantnej skupiny. Keď JVM vyhľadá constant_pool [this_class], nájde prvok, ktorý sa so svojou značkou identifikuje ako CONSTANT_Class. JVM vie, že prvky CONSTANT_Class majú vždy po svojom jednobajtovom tagu dvojbajtový index do konštantnej oblasti nazývaný index indexu. Takže vyhľadá constant_pool [name_index], aby získal reťazec obsahujúci názov triedy alebo rozhrania.

Super trieda

Nasleduj tejto triedy zložkou je super trieda komponent, ďalší dvojbajtový index do konštantnej oblasti. Constant_pool [super_class] je prvok CONSTANT_Class, ktorý ukazuje na názov super triedy, z ktorej táto trieda pochádza.

Rozhrania

Komponenta rozhrania začína dvojbajtovým počtom rozhraní implementovaných triedou (alebo rozhraním) definovanou v súbore. Okamžite nasleduje pole, ktoré obsahuje jeden index do konštantnej oblasti pre každé rozhranie implementované triedou. Každé rozhranie je reprezentované prvkom CONSTANT_Class v skupine konštánt, ktorá ukazuje na názov rozhrania.

Polia

Komponent pole začína dvojbajtovým počtom polí v tejto triede alebo rozhraní. Pole je premenná inštancie alebo triedy triedy alebo rozhrania. Nasleduje počet štruktúr s premennou dĺžkou, jedna pre každé pole. Každá štruktúra odhaľuje informácie o jednom poli, ako je názov, typ a, ak ide o konečnú premennú, jej konštantná hodnota. Niektoré informácie sú obsiahnuté v samotnej štruktúre a niektoré sú obsiahnuté v konštantných umiestneniach spoločného fondu, na ktoré ukazuje štruktúra.

Jediné polia, ktoré sa zobrazia v zozname, sú tie, ktoré boli deklarované triedou alebo rozhraním definovaným v súbore; v zozname sa neobjavujú žiadne polia zdedené zo super tried alebo super rozhraní.

Metódy

Komponent metódy začína dvojbajtovým počtom počtu metód v triede alebo rozhraní. Tento počet zahŕňa iba tie metódy, ktoré sú výslovne definované touto triedou, nie všetky metódy, ktoré môžu byť zdedené zo supertried. Podľa počtu metód nasledujú samotné metódy.

Štruktúra každej metódy obsahuje niekoľko informácií o metóde, vrátane deskriptora metódy (jej návratový typ a zoznam argumentov), ​​počtu slov v zásobníku požadovaných pre miestne premenné metódy, maximálneho počtu slov v zásobníku požadovaného pre operand metódy stack, tabuľku výnimiek zachytených metódou, postupnosť bajtových kódov a tabuľku čísel riadkov.

Atribúty

Na zadnej strane sú atribúty, ktoré poskytujú všeobecné informácie o konkrétnej triede alebo rozhraní definovanom v súbore. Sekcia atribútov má počet bajtov počtu atribútov a za nimi nasledujú samotné atribúty. Napríklad jeden atribút je atribút zdrojového kódu; odhaľuje názov zdrojového súboru, z ktorého bol tento súbor triedy zostavený. Spoločnosti JVM budú ticho ignorovať všetky atribúty, ktoré neuznávajú.

Načítanie: simulácia súboru triedy, ktorý sa dostane do cieľa JVM

Nižšie uvedený applet simuluje JVM načítavajúci súbor triedy. Súbor triedy, ktorý sa načítal do simulácie, vygeneroval kompilátor javac s nasledujúcim zdrojovým kódom Java:

class Act {public static void doMathForever () {int i = 0; while (true) {i + = 1; i * = 2; }}} 

Vyššie uvedený úryvok kódu pochádza z článku o JVM z minulého mesiaca. Je to rovnaká metóda doMathForever (), ktorú vykonal applet EternalMath z článku z minulého mesiaca. Tento kód som vybral, aby som poskytol skutočný príklad, ktorý nebol príliš zložitý. Aj keď kód nemusí byť v reálnom svete veľmi užitočný, kompiluje sa do súboru skutočnej triedy, ktorý sa načíta pomocou nižšie uvedenej simulácie.

Applet GettingLoaded vám umožňuje riadiť simuláciu zaťaženia triedy jeden krok po druhom. Pri každom kroku na tejto ceste si môžete prečítať o ďalšom bloku bajtov, ktorý má JVM spotrebovať a interpretovať. Stačí stlačiť tlačidlo „Krok“ a spôsobí, že JVM spotrebuje ďalší blok. Stlačením tlačidla „Späť“ sa vráti predchádzajúci krok a stlačením tlačidla „Obnoviť“ sa vráti simulácia do pôvodného stavu, čo vám umožní začať odznova.

JVM je zobrazený vľavo dole a spotrebúva prúd bajtov, ktorý tvorí súbor triedy Act.class. Bajty sú zobrazené v hexadecimálnom formáte vychádzajúcom zo servera vpravo dole. Bajty sa pohybujú sprava doľava medzi serverom a JVM po jednom kuse. Kus bajtov, ktoré spotrebuje JVM pri ďalšom stlačení tlačidla „Krok“, sa zobrazuje červenou farbou. Tieto zvýraznené bajty sú opísané vo veľkej textovej oblasti nad JVM. Všetky zostávajúce bajty za ďalším diskovým blokom sú zobrazené čiernou farbou.

Snažil som sa úplne vysvetliť každý kúsok bajtu v textovej oblasti. V textovej oblasti je preto veľa podrobností a možno budete chcieť najskôr prejsť všetky kroky, aby ste získali všeobecnú predstavu, a potom sa pozrieť dozadu a získať ďalšie podrobnosti.

Šťastné klikanie.

Na prezeranie tohto appletu potrebujete prehliadač s podporou Java.

Kliknite sem, aby ste dostali zdrojový kód GettingLoaded. Ak chcete tento applet spustiť sami, budete tiež potrebovať dva súbory, ktoré tento applet načítava zo servera, súbor ASCII, ktorý obsahuje text pre každý krok, a samotný súbor Act.class. Kliknite sem, aby ste dostali zdrojový kód zvukového appletu Flying Class Files.

ENDNOTE: Malé písmo: Článok „Životný štýl súboru Java Class“ Autorské právo (c) 1996 Bill Venners. Všetky práva vyhradené. Autorské právo na aplikáciu „GettingLoaded“ (c) 1996 Artima Software Company. Všetky práva vyhradené.

: END_ENDPOZNÁMKA

Bill Venners je prezidentom spoločnosti Artima Software Company. Prostredníctvom spoločnosti Artima robí vývoj softvéru na zákazku a poradenstvo.

Získajte viac informácií o tejto téme

  • Špecifikácia Java Virtual Machine, oficiálne slovo od spoločnosti Sun.

    //java.sun.com/1.0alpha3/doc/vmspec/vmspec_1.html

  • Keď to vyjde, kniha Špecifikácia virtuálneho počítača Java, //www.aw.com/cp/lindholm-yellin.html, autormi Tim Lindholm a Frank Yellin (ISBN 0-201-63452-X), súčasť série Java, //www.aw.com/cp/ javaseries.html), z Addison-Wesley, bude pravdepodobne najlepším zdrojom JVM.
  • Návrh kapitoly 4 z Špecifikácia virtuálneho stroja Java, ktorý popisuje formát súboru triedy a overovač bytecode, je možné získať z JavaSoftu.

    //java.sun.com/java.sun.com/newdocs.html

Tento príbeh „Životný štýl súborov triedy Java“ pôvodne publikoval server JavaWorld.

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