Soubor třídy Java - Java class file - Wikipedia
Vyvinul | Sun Microsystems |
---|
A Soubor třídy Java je soubor (s .třída přípona souboru ) obsahující Bajtový kód Java které lze provést na Java Virtual Machine (JVM). Soubor třídy Java obvykle produkuje a Překladač Java z Programovací jazyk Java zdrojové soubory (.Jáva soubory) obsahující Javu třídy (alternativně jiné JVM jazyky lze také použít k vytvoření souborů třídy). Pokud má zdrojový soubor více než jednu třídu, je každá třída zkompilována do samostatného souboru třídy.
JVM jsou k dispozici pro mnoho platformy a soubor třídy zkompilovaný na jedné platformě se spustí na JVM jiné platformy. Díky tomu jsou Java aplikace nezávislý na platformě.
Dějiny
Dne 11. Prosince 2006 byl formát souboru třídy upraven pod Žádost o specifikaci Java (JSR) 202.[1]
Rozložení a struktura souborů
Sekce
Struktura souboru tříd Java obsahuje 10 základních sekcí:
- Magické číslo: 0xCAFEBABE
- Verze formátu souboru třídy: vedlejší a hlavní verze souboru třídy
- Konstantní bazén: Soubor konstant pro třídu
- Přístupové vlajky: například zda je třída abstraktní, statická atd.
- Tato třída: Název aktuální třídy
- Super třída: Název super třídy
- Rozhraní: Jakákoli rozhraní ve třídě
- Pole: Jakákoli pole ve třídě
- Metody: Jakékoli metody ve třídě
- Atributy: Jakékoli atributy třídy (například název zdrojového souboru atd.)
Magické číslo
Soubory tříd jsou označeny následujícími 4 byte záhlaví (v hexadecimální ): CA FE BA BE
(první 4 položky v tabulce níže). Historie toho magické číslo vysvětlil James Gosling s odkazem na restauraci v Palo Alto:[2]
„Chodili jsme na oběd do místa zvaného St Michael's Alley. Podle místní legendy v hluboké temné minulosti Vděčná smrt kdysi tam vystupovali, než to udělali velkým. Bylo to docela funky místo, které rozhodně bylo Grateful Dead Kinda Place. Když Jerry zemřeli, postavili dokonce malou svatyni v buddhistickém stylu. Když jsme tam chodili, označovali jsme to místo jako Cafe Dead. Někde na trati si všimli, že se jedná o hexadecimální číslo. Znovu jsem vampoval nějaký kód formátu souboru a potřeboval jsem pár magická čísla: jeden pro soubor trvalých objektů a jeden pro třídy. Použil jsem CAFEDEAD pro formát souboru objektu a v zdravím pro čtyřmístná hexadecimální slova, která se vešly za „CAFE“ (zdálo se, že je to dobré téma), jsem narazil na BABE a rozhodl jsem se jej použít. V té době se mi to nezdálo strašně důležité nebo předurčené jít kamkoli kromě koše - plechovka historie. CAFEBABE se tedy stal formátem souboru třídy a CAFEDEAD byl formát trvalého objektu. Zařízení pro trvalé objekty ale zmizelo a spolu s ním začalo i používání CAFEDEAD - ten byl nakonec nahrazen RMI.
Obecné rozložení
Protože soubor třídy obsahuje položky s proměnnou velikostí a neobsahuje také posuny vloženého souboru (nebo ukazatele), je obvykle analyzován postupně, od prvního bajtu ke konci. Na nejnižší úrovni je formát souboru popsán z hlediska několika základních datových typů:
- u1: nepodepsaný 8-bit celé číslo
- u2: nepodepsaný 16-bit integer in big-endian pořadí bytů
- u4: nepodepsaný 32-bit celé číslo v pořadí bajtů big-endian
- stůl: pole položek proměnné délky nějakého typu. Počet položek v tabulce je identifikován podle předchozího počtu (počet je u2), ale velikost v bajtech tabulky lze určit pouze prozkoumáním každé z jejích položek.
Některé z těchto základních typů jsou poté znovu interpretovány jako hodnoty vyšší úrovně (například řetězce nebo čísla s plovoucí desetinnou čárkou), v závislosti na kontextu. Neexistuje žádné vynucování zarovnání slov, a proto se nikdy nepoužívají žádné výplňové bajty. souboru třídy je uvedeno v následující tabulce.
offset bytu | velikost | typ nebo hodnota | popis |
---|---|---|---|
0 | 4 byty | u1 = 0xCA hex | magické číslo (CAFEBABE) slouží k identifikaci souboru jako vyhovujícího formátu souboru třídy |
1 | u1 = 0xFE hex | ||
2 | u1 = 0xBA hex | ||
3 | u1 = 0xBE hex | ||
4 | 2 bajty | u2 | vedlejší číslo verze použitého formátu souboru třídy |
5 | |||
6 | 2 bajty | u2 | hlavní číslo verze používaného formátu souboru třídy. Java SE 15 = 59 (0x3B hex), |
7 | |||
8 | 2 bajty | u2 | konstantní počet bazénů, počet záznamů v následující tabulce konstantních bazénů. Tento počet je alespoň o jeden větší než skutečný počet záznamů; viz následující diskuse. |
9 | |||
10 | cpsize (proměnná) | stůl | konstantní kulečníková tabulka, pole položek konstantní skupiny proměnné velikosti, které obsahují položky, jako jsou doslovná čísla, řetězce a odkazy na třídy nebo metody. Indexováno od 1, obsahující (konstantní počet bazénů - 1) celkový počet záznamů (viz poznámka). |
... | |||
... | |||
... | |||
10+cpsize | 2 bajty | u2 | příznaky přístupu, bitová maska |
11+cpsize | |||
12+cpsize | 2 bajty | u2 | identifikuje tento třída, indexujte do fondu konstant na položku typu „Třída“ |
13+cpsize | |||
14+cpsize | 2 bajty | u2 | identifikuje super třída, indexujte do fondu konstant na položku typu „Třída“ |
15+cpsize | |||
16+cpsize | 2 bajty | u2 | počet rozhraní, počet položek v následující tabulce rozhraní |
17+cpsize | |||
18+cpsize | isize (proměnná) | stůl | tabulka rozhraní: pole proměnných délek indexů konstantních fondů popisujících rozhraní implementovaná touto třídou |
... | |||
... | |||
... | |||
18+cpsize+isize | 2 bajty | u2 | počet polí, počet záznamů v následující tabulce polí |
19+cpsize+isize | |||
20+cpsize+isize | fsize (proměnná) | stůl | tabulka polí, pole polí s proměnnou délkou každý prvek je struktura field_info definovaná v https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5 |
... | |||
... | |||
... | |||
20+cpsize+isize+fsize | 2 bajty | u2 | počet metod, počet záznamů v následující tabulce metod |
21+cpsize+isize+fsize | |||
22+cpsize+isize+fsize | msize (proměnná) | stůl | tabulka metod, pole metod s proměnnou délkou každý prvek je method_info struktura definovaná v https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6 |
... | |||
... | |||
... | |||
22+cpsize+isize+fsize+msize | 2 bajty | u2 | počet atributů, počet položek v následující tabulce atributů |
23+cpsize+isize+fsize+msize | |||
24+cpsize+isize+fsize+msize | velikost (proměnná) | stůl | tabulka atributů, pole atributů s proměnnou délkou každý prvek je struktura atribut_info definovaná v https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7 |
... | |||
... | |||
... |
Zastoupení v programovacím jazyce typu C.
Od té doby C nepodporuje více polí s proměnnou délkou v rámci struktury, níže uvedený kód nebude kompilován a slouží pouze jako demonstrace.
struktur Class_File_Format { u4 magické_číslo; u2 minor_version; u2 major_version; u2 konstantní_počet_počtu; cp_info Constant_pool[stálý_počet_počtu - 1]; u2 příznaky přístupu; u2 tato třída; u2 super_třída; u2 interfaces_count; u2 rozhraní[interfaces_count]; u2 pole_počet; field_info pole[pole_počet]; u2 metody_počet; metoda_info metody[metody_počet]; u2 atributy_počet; atribut_info atributy[atributy_počet];}
Konstantní bazén
Konstantní kulečníková tabulka je místo, kde je uložena většina doslovných hodnot konstanty. To zahrnuje hodnoty, jako jsou čísla všech druhů, řetězce, názvy identifikátorů, odkazy na třídy a metody a deskriptory typů. Všechny indexy nebo odkazy na konkrétní konstanty v tabulce konstantních bazénů jsou dány 16bitovými čísly (typ u2), kde hodnota indexu 1 odkazuje na první konstantu v tabulce (hodnota indexu 0 je neplatná).
Kvůli historickým volbám provedeným během vývoje formátu souboru není počet konstant v tabulce konstantních bazénů ve skutečnosti stejný jako počet konstantních fondů, který předchází tabulku. Nejprve je tabulka indexována od 1 (spíše než 0), ale počet by měl být ve skutečnosti interpretován jako maximální index plus jedna.[5] Kromě toho dva typy konstant (dlouhé a zdvojnásobené) zabírají dva po sobě jdoucí sloty v tabulce, ačkoli druhý takový slot je fantomový index, který se nikdy přímo nepoužívá.
Typ každé položky (konstanty) ve fondu konstant je identifikován počátečním bajtem štítek. Počet bajtů následujících po tomto tagu a jejich interpretace jsou pak závislé na hodnotě tagu. Platné typy konstant a jejich hodnoty značek jsou:
Označit bajt | Další bajty | Popis konstanty | Verze představena |
---|---|---|---|
1 | 2+X bajtů (proměnná) | Řetězec UTF-8 (Unicode): řetězec znaků s předponou 16bitového čísla (typ u2) označující počet bajtů v kódovaném řetězci, který bezprostředně následuje (který se může lišit od počtu znaků). Všimněte si, že použité kódování ve skutečnosti není UTF-8, ale zahrnuje mírnou úpravu standardního kódovacího formuláře Unicode. | 1.0.2 |
3 | 4 byty | Celé číslo: podepsaný 32bitový doplněk dvou číslo ve formátu big-endian | 1.0.2 |
4 | 4 byty | Float: 32bitová přesnost s jednou přesností IEEE 754 číslo s plovoucí desetinnou čárkou | 1.0.2 |
5 | 8 bytů | Long: podepsané 64bitové číslo dvou doplňků ve formátu big-endian (trvá dva sloty v konstantní kulečníkové tabulce) | 1.0.2 |
6 | 8 bytů | Double: 64bitové číslo s plovoucí desetinnou čárkou IEEE 754 s dvojitou přesností (zabírá dva sloty v konstantní kulové tabulce) | 1.0.2 |
7 | 2 bajty | Odkaz na třídu: index v rámci fondu konstant na řetězec UTF-8 obsahující plně kvalifikovaný název třídy (v interní formát) (big-endian) | 1.0.2 |
8 | 2 bajty | Řetězcový odkaz: index v rámci konstantního fondu na řetězec UTF-8 (také big-endian) | 1.0.2 |
9 | 4 byty | Odkaz na pole: dva indexy v rámci fondu konstant, první ukazuje na odkaz na třídu, druhý na deskriptor názvu a typu. (big-endian) | 1.0.2 |
10 | 4 byty | Odkaz na metodu: dva indexy v rámci fondu konstant, první ukazuje na odkaz na třídu, druhý na deskriptor názvu a typu. (big-endian) | 1.0.2 |
11 | 4 byty | Odkaz na metodu rozhraní: dva indexy v rámci fondu konstant, první ukazuje na odkaz na třídu, druhý na deskriptor názvu a typu. (big-endian) | 1.0.2 |
12 | 4 byty | Deskriptor názvu a typu: dva indexy řetězců UTF-8 v rámci fondu konstant, první představuje název (identifikátor) a druhý speciálně kódovaný deskriptor typu. | 1.0.2 |
15 | 3 bajty | Popisovač metody: tato struktura se používá k reprezentaci popisovače metody a skládá se z jednoho bajtu deskriptoru typu, následovaného indexem v rámci fondu konstant.[5] | 7 |
16 | 2 bajty | Typ metody: tato struktura se používá k reprezentaci typu metody a skládá se z indexu v rámci fondu konstant.[5] | 7 |
17 | 4 byty | Dynamický: používá se k určení dynamicky vypočítané konstanty vytvořené vyvoláním metody bootstrap.[5] | 11 |
18 | 4 byty | InvokeDynamic: toto používá invokedynamic instrukce k určení metody bootstrapu, názvu dynamického vyvolání, typů argumentů a návratů volání a volitelně sekvence dalších konstant nazývaných statické argumenty metody bootstrap.[5] | 7 |
19 | 2 bajty | Modul: slouží k identifikaci modulu.[5] | 9 |
20 | 2 bajty | Balíček: slouží k identifikaci balíčku exportovaného nebo otevřeného modulem.[5] | 9 |
Existují pouze dva typy integrálních konstant, integer a long. Jiné integrální typy, které se objevují v jazyce vyšší úrovně, například boolean, byte a short, musí být reprezentovány jako celočíselná konstanta.
Pokud jsou názvy tříd v Javě plně kvalifikované, jsou tradičně odděleny tečkami, například „java.lang.Object“. V rámci nízkoúrovňových referenčních konstant třídy se však objeví interní formulář, který místo toho používá lomítka, například „java / lang / Object“.
Řetězce Unicode, navzdory přezdívce „řetězec UTF-8“, nejsou ve skutečnosti kódovány podle standardu Unicode, i když je to podobné. Existují dva rozdíly (viz UTF-8 pro úplnou diskusi). První je, že kódový bod U + 0000 je kódován jako dvoubajtová sekvence C0 80
(v hexadecimálním formátu) namísto standardního jednobajtového kódování 00
. Druhým rozdílem je to, že doplňkové znaky (ty mimo BMP na U + 10 000 a výše) jsou kódovány pomocí konstrukce náhradních párů podobné UTF-16 místo přímého kódování pomocí UTF-8. V tomto případě je každý ze dvou náhradních kódů samostatně kódován v UTF-8. Například U + 1D11E je kódován jako 6bajtová sekvence ED A0 B4 ED B4 9E
, spíše než správné 4bajtové kódování UTF-8 F0 9D 84 9E
.
Viz také
Reference
- ^ JSR 202 Aktualizace specifikace souboru třídy Java
- ^ James Gosling soukromá komunikace s Billem Bumgarnerem
- ^ http://www.oracle.com/technetwork/java/javase/10-relnote-issues-4108729.html#Remaining
- ^ https://bugs.openjdk.java.net/browse/JDK-8148785
- ^ A b C d E F G https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.4
Další čtení
- Tim Lindholm Frank Yellin (1999). Specifikace Java Virtual Machine (Druhé vydání.). Prentice Hall. ISBN 0-201-43294-3. Citováno 2008-10-13. Oficiální definiční dokument EU Virtuální stroj Java, který zahrnuje formát souboru třídy. První i druhé vydání knihy jsou volně dostupné online pro prohlížení a / nebo stahování.