Programování

Životní styl souborů třídy Java

Vítejte v další části hry „Pod kapotou“. V článku z minulého měsíce jsem pojednával o Java Virtual Machine neboli JVM, abstraktním počítači, pro který jsou kompilovány všechny programy Java. Pokud nejste obeznámeni s JVM, možná si budete chtít přečíst článek z minulého měsíce před tímto. V tomto článku poskytuji letmý pohled na základní strukturu a životní styl souboru třídy Java.

Zrozen k cestování

Soubor třídy Java je přesně definovaný formát pro kompilovanou Javu. Zdrojový kód Java je kompilován do souborů tříd, které lze načíst a spustit jakýmkoli JVM. Soubory třídy mohou cestovat přes síť, než je načte JVM.

Ve skutečnosti, pokud čtete tento článek prostřednictvím prohlížeče podporujícího prostředí Java, soubory tříd pro simulační applet na konci článku právě teď létají přes internet do vašeho počítače. Pokud je chcete poslouchat (a váš počítač má zvukové schopnosti), stiskněte následující tlačítko:

K prohlížení tohoto appletu potřebujete prohlížeč s podporou Java

Zní to, jako by se bavili, hm? To je v jejich povaze. Soubory třídy Java byly navrženy tak, aby dobře cestovaly. Jsou nezávislé na platformě, takže budou vítáni na více místech. Obsahují bytecodes, kompaktní instrukční sadu pro JVM, takže mohou cestovat lehce. Soubory třídy Java neustále procházejí sítěmi závratnou rychlostí, aby se dostaly k JVM po celém světě.

Co je v souboru třídy?

Soubor třídy Java obsahuje vše, co JVM potřebuje vědět o jedné třídě nebo rozhraní Java. V pořadí, v jakém se objevují v souboru třídy, jsou hlavní komponenty: magie, verze, konstantní fond, příznaky přístupu, tato třída, super třída, rozhraní, pole, metody a atributy.

Informace uložené v souboru třídy se často liší v délce - to znamená, že skutečnou délku informací nelze předpovědět před načtením souboru třídy. Například počet metod uvedených v komponentě metody se může mezi soubory tříd lišit, protože to závisí na počtu metod definovaných ve zdrojovém kódu. Takové informace jsou uspořádány v souboru třídy tak, že předloží aktuální informace podle jejich velikosti nebo délky. Tímto způsobem, když je třída načítána JVM, je nejprve čtena velikost informací o proměnné délce. Jakmile JVM zná velikost, může správně načíst skutečné informace.

Informace se obvykle zapisují do souboru třídy bez mezery nebo polstrování mezi po sobě následujícími informacemi; vše je zarovnáno na hranicích bajtů. To pomáhá udržovat soubory třídy drobné, takže při letu napříč sítěmi budou aerodynamické.

Pořadí komponent souboru třídy je přísně definováno, takže JVM mohou vědět, co mohou očekávat a kde to mohou očekávat při načítání souboru třídy. Například každý JVM ví, že prvních osm bajtů souboru třídy obsahuje čísla magie a verze, že konstantní fond začíná devátým bajtem a že příznaky přístupu sledují konstantní fond. Ale protože konstantní fond má proměnnou délku, nezná přesné místo, kde se nacházejí příznaky přístupu, dokud nedokončí čtení v konstantním fondu. Jakmile dokončí čtení v konstantním fondu, ví, že další dva bajty budou příznaky přístupu.

Kouzla a čísla verzí

První čtyři bajty každého souboru třídy jsou vždy 0xCAFEBABE. Toto kouzelné číslo usnadňuje identifikaci souborů třídy Java, protože je malá pravděpodobnost, že soubory jiné třídy by začaly se stejnými počátečními čtyřmi bajty. Číslo se nazývá magické, protože ho návrháři formátů souborů mohou vytáhnout z klobouku. Jediným požadavkem je, že již není používán jiným formátem souboru, se kterým se ve skutečném světě setkáváme. Podle Patricka Naughtona, klíčového člena původního týmu Java, bylo magické číslo zvoleno „dlouho předtím, než se někdy v souvislosti s tímto jazykem vyslovilo jméno Java. Hledali jsme něco zábavného, ​​jedinečného a snadno zapamatovatelného. jen náhoda, že OxCAFEBABE, šikmý odkaz na roztomilé baristy v Peet's Coffee, byl předzvěstí jména Java. “

Druhé čtyři bajty souboru třídy obsahují čísla hlavní a vedlejší verze. Tato čísla identifikují verzi formátu souboru třídy, kterého se konkrétní soubor třídy drží, a umožňují JVM ověřit, že je soubor třídy možné načíst. Každý JVM má maximální verzi, kterou může načíst, a JVM odmítne soubory třídy s novějšími verzemi.

Konstantní bazén

Soubor třídy ukládá konstanty spojené s jeho třídou nebo rozhraním ve fondu konstant. Některé konstanty, které mohou být viděny ve fondu, jsou doslovné řetězce, konečné hodnoty proměnných, názvy tříd, názvy rozhraní, názvy a typy proměnných a názvy metod a podpisy. Metoda podpis je jeho návratový typ a sada typů argumentů.

Konstantní fond je organizován jako řada prvků s proměnnou délkou. Každá konstanta zabírá jeden prvek v poli. V celém souboru třídy jsou konstanty označovány celočíselným indexem, který označuje jejich pozici v poli. Počáteční konstanta má index jeden, druhá konstanta má index dva atd. Konstantnímu poli fondu předchází jeho velikost pole, takže JVM budou vědět, kolik konstant očekávat při načítání souboru třídy.

Každý prvek fondu konstant začíná jednobajtovou značkou určující typ konstanty na dané pozici v poli. Jakmile JVM uchopí a interpretuje tuto značku, ví, co po ní následuje. Například pokud značka označuje, že konstanta je řetězec, JVM očekává, že další dva bajty budou mít délku řetězce. Po této délce dvou bytů očekává JVM, že ji najde délka počet bajtů, které tvoří znaky řetězce.

Ve zbývající části článku budu někdy označovat n-tý prvek pole konstantního fondu jako constant_pool [n]. To dává smysl do té míry, že konstantní fond je organizován jako pole, ale mějte na paměti, že tyto prvky mají různé velikosti a typy a že první prvek má index jednoho.

Přístupové příznaky

První dva bajty za konstantním fondem, příznaky přístupu, označují, zda tento soubor definuje třídu nebo rozhraní, zda je třída nebo rozhraní veřejné nebo abstraktní, a (je-li to třída a ne rozhraní), zda je třída je konečný.

Tato třída

Další dva bajty, tato třída komponenta, jsou indexem do pole konstantního fondu. Konstanta, na kterou odkazuje tato třída, constant_pool [this_class], má dvě části, jednobajtovou značku a dvoubajtový index jmen. Značka se bude rovnat CONSTANT_Class, hodnota, která označuje tento prvek, obsahuje informace o třídě nebo rozhraní. Constant_pool [name_index] je řetězcová konstanta obsahující název třídy nebo rozhraní.

The tato třída komponenta poskytuje pohled na to, jak se používá konstantní fond. Tato třída sám o sobě je jen indexem do konstantního fondu. Když JVM vyhledá constant_pool [this_class], najde prvek, který se se svou značkou identifikuje jako CONSTANT_Class. JVM ví, že prvky CONSTANT_Class mají vždy dvoubajtový index do fondu konstant nazývaný index jmen, který následuje za jejich jednobajtovou značkou. Vyhledá tedy constant_pool [name_index] a získá řetězec obsahující název třídy nebo rozhraní.

Super třída

V návaznosti na tato třída složka je super třída komponenta, další dvoubajtový index do fondu konstant. Constant_pool [super_class] je prvek CONSTANT_Class, který ukazuje na název super třídy, ze které tato třída sestupuje.

Rozhraní

Komponenta rozhraní začíná dvojbajtovým počtem rozhraní implementovaných třídou (nebo rozhraním) definovanou v souboru. Okamžitě následuje pole, které obsahuje jeden index do fondu konstant pro každé rozhraní implementované třídou. Každé rozhraní je reprezentováno prvkem CONSTANT_Class ve fondu konstant, který ukazuje na název rozhraní.

Pole

Komponenta pole začíná dvoubajtovým počtem polí v této třídě nebo rozhraní. Pole je proměnná instance nebo třídy třídy nebo rozhraní. Následuje počet struktur proměnné délky, jedna pro každé pole. Každá struktura odhaluje informace o jednom poli, jako je název, typ pole, a pokud se jedná o konečnou proměnnou, jeho konstantní hodnota. Některé informace jsou obsaženy v samotné struktuře a některé jsou obsaženy v konstantních umístěních fondu, na které ukazuje struktura.

V seznamu se objeví pouze pole, která byla deklarována třídou nebo rozhraním definovaným v souboru; v seznamu se neobjeví žádná pole zděděná ze super tříd nebo super rozhraní.

Metody

Komponenta metod začíná dvoubajtovým počtem metod ve třídě nebo rozhraní. Tento počet zahrnuje pouze ty metody, které jsou explicitně definovány touto třídou, nikoli žádné metody, které mohou být zděděny ze supertříd. Po počtu metod následují samotné metody.

Struktura pro každou metodu obsahuje několik informací o metodě, včetně deskriptoru metody (její návratový typ a seznam argumentů), počet slov zásobníku potřebných pro místní proměnné metody, maximální počet slov zásobníku vyžadovaných pro operand metody zásobník, tabulka výjimek zachycená metodou, sekvence bajtových kódů a tabulka čísel řádků.

Atributy

V zadní části jsou atributy, které poskytují obecné informace o konkrétní třídě nebo rozhraní definovaném souborem. Sekce atributů má počet bajtů počtu atributů, za nimiž následují samotné atributy. Například jeden atribut je atribut zdrojového kódu; odhalí název zdrojového souboru, ze kterého byl tento soubor třídy sestaven. JVM budou tiše ignorovat všechny atributy, které nerozpoznají.

Načítání: simulace souboru třídy, který dosáhne svého cíle JVM

Níže uvedený applet simuluje JVM načítající soubor třídy. Soubor třídy, který se načítá v simulaci, vygeneroval kompilátor javac vzhledem k následujícímu zdrojovému kódu Java:

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

Výše uvedený fragment kódu pochází z článku o JVM z minulého měsíce. Je to stejná metoda doMathForever (), kterou provádí applet EternalMath z článku z minulého měsíce. Tento kód jsem vybral, abych poskytl skutečný příklad, který nebyl příliš složitý. Ačkoli kód nemusí být v reálném světě příliš užitečný, kompiluje se do souboru skutečné třídy, který je načten níže uvedenou simulací.

Applet GettingLoaded umožňuje řídit simulaci zatížení třídy jeden krok po druhém. U každého kroku si můžete přečíst o dalším bloku bajtů, který má JVM spotřebovat a interpretovat. Stačí stisknout tlačítko „Krok“ a způsobí, že JVM spotřebuje další blok. Stisknutím tlačítka „Zpět“ vrátíte předchozí krok a stisknutím tlačítka „Obnovit“ vrátíte simulaci do původního stavu, což vám umožní začít znovu od začátku.

JVM je zobrazen vlevo dole a spotřebovává proud bajtů, který tvoří soubor třídy Act.class. Bajty jsou zobrazeny v hexadecimálním streamování ze serveru vpravo dole. Bajty cestují zprava doleva, mezi serverem a JVM, jeden kus po druhém. Kus bajtů, které JVM spotřebuje při dalším stisknutí tlačítka „Krok“, se zobrazí červeně. Tyto zvýrazněné bajty jsou popsány ve velké textové oblasti nad JVM. Jakékoli zbývající bajty nad další blok jsou zobrazeny černě.

Snažil jsem se plně vysvětlit každý blok bajtů v textové oblasti. V textové oblasti je proto spousta podrobností a možná budete chtít nejprve projít všechny kroky, abyste získali obecnou představu, a pak se podívat zpět pro další podrobnosti.

Šťastné kliknutí.

K prohlížení tohoto appletu potřebujete prohlížeč s podporou Java.

Kliknutím sem zobrazíte zdrojový kód GettingLoaded. Chcete-li tento applet spustit samostatně, budete také potřebovat dva soubory, které tento applet načte ze serveru, soubor ASCII, který obsahuje text pro každý krok, a samotný soubor Act.class. Kliknutím sem zobrazíte zdrojový kód zvukového appletu Flying Class Files.

ENDNOTE: Malé písmo: "The Java Class File Lifestyle" Článek Copyright (c) 1996 Bill Venners. Všechna práva vyhrazena. Copyright (c) 1996 Artima Software Company, „GettingLoaded“. Všechna práva vyhrazena.

: END_ENDPOZNÁMKA

Bill Venners je prezidentem Artima Software Company. Prostřednictvím Artima se věnuje vývoji a poradenství na zakázku.

Další informace o tomto tématu

  • Specifikace Java Virtual Machine, oficiální slovo od společnosti Sun.

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

  • Když to vyjde, kniha Specifikace Java Virtual Machine, //www.aw.com/cp/lindholm-yellin.html, Tim Lindholm a Frank Yellin (ISBN 0-201-63452-X), součást série Java, //www.aw.com/cp/ javaseries.html) z Addison-Wesley bude pravděpodobně nejlepším prostředkem JVM.
  • Návrh kapitoly 4 z Specifikace Java Virtual Machine, který popisuje formát souboru třídy a ověřovač bytecode, lze získat z JavaSoft.

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

Tento příběh „Životní styl souborů třídy Java“ původně publikoval JavaWorld.

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