Soubor třídy Java - Java class file

Soubor třídy Java
Typ internetového média aplikace/java-vm, aplikace/x-httpd-java
Vyvinuto Sun Microsystems

Soubor třídy Java je soubor (s příponou názvu souboru .class ) obsahující bajtový kód Java, který lze spustit na Java Virtual Machine (JVM) . Soubor třídy Java obvykle vytváří kompilátor jazyka Java ze zdrojových souborů programovacího jazyka Java ( soubory .java ) obsahujících třídy Java (alternativně lze k vytváření souborů tříd použít také jiné jazyky JVM ). 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 platforem a soubor třídy kompilovaný na jedné platformě se spustí na JVM jiné platformy. Díky tomu jsou aplikace Java nezávislé na platformě .

Dějiny

Dne 11. prosince 2006 byl formát souboru třídy upraven v rámci Java Specification Request (JSR) 202.

Rozložení a struktura souboru

Sekce

Struktura souboru třídy Java obsahuje 10 základních částí:

  • Magické číslo : 0xCAFEBABE
  • Verze formátu souboru třídy : vedlejší a hlavní verze souboru třídy
  • Constant Pool : Pool of constants for the class
  • Přístupové příznaky : 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 : Všechny metody ve třídě
  • Atributy : Libovolné atributy třídy (například název zdrojového souboru atd.)

Magické číslo

Soubory tříd jsou označeny následujícím záhlavím se 4 bajty (v šestnáctkové soustavě ): (první 4 položky v níže uvedené tabulce). Historii tohoto magického čísla vysvětlil James Gosling s odkazem na restauraci v Palo Alto : CA FE BA BE

„Chodili jsme na oběd na místo zvané St Michael's Alley. Podle místní legendy tam v hluboké temné minulosti Grateful Dead vystupovali, než se proslavili. Bylo to docela funky místo, které rozhodně bylo Grateful Dead Kinda Place. Když Jerry zemřel, dokonce postavili malou buddhistickou svatyni. Když jsme tam chodili, říkali jsme tomu místu jako Cafe Dead. Někde podél čáry si všimli, že to bylo HEX číslo. I přepracoval nějaký kód formátu souboru a potřeboval pár kouzelných čísel : jedno pro soubor trvalých objektů a jedno pro třídy. Použil jsem CAFEDEAD pro formát souboru objektu a při grepování pro 4 znaková hexadecimální slova, která se hodí po „CAFE "(Zdálo se, že je to dobré téma) Trefil jsem se do BABE a rozhodl jsem se to použít. V té době mi to nepřipadalo nijak zvlášť důležité ani předurčené někam jít, než do popelnice historie. Takže CAFEBABE se stal třídním souborem formát a CAFEDEAD byl formát trvalého objektu. Zařízení trvalých objektů však přešlo ano, a spolu s tím šlo použití CAFEDEAD - nakonec byl nahrazen RMI .

Obecné rozložení

Protože soubor třídy obsahuje položky proměnné velikosti a neobsahuje také vložené posuny souborů (nebo ukazatele), je obvykle analyzován postupně, od prvního bajtu ke konci. Na nejnižší úrovni je formát souboru popsán pomocí několika základních datových typů:

  • u1 : 8bitové celé číslo bez znaménka
  • u2 : 16bitové celé číslo bez znaménka v pořadí bajtů big-endian
  • u4 : 32bitové celé číslo bez znaménka v pořadí bajtů big-endian
  • tabulka : pole položek proměnné délky nějakého typu. Počet položek v tabulce je identifikován předchozím číslem (počet je u2), ale velikost tabulky v bajtech lze určit pouze prozkoumáním každé z jejích položek.

Některé z těchto základních typů jsou pak znovu interpretovány jako hodnoty vyšší úrovně (například řetězce nebo čísla s plovoucí desetinnou čárkou), v závislosti na kontextu. Neexistuje vynucování zarovnání slov, a proto se nikdy nepoužívají žádné výplňové bajty. Celkové rozložení souboru třídy je uvedeno v následující tabulce.

offset bajtů velikost typ nebo hodnota popis
0 4 byty u1 =
0xCA hex
magické číslo (CAFEBABE) používané k identifikaci souboru, který odpovídá formátu souboru třídy
1 u1 =
0xFE hex
2 u1 =
0xBA hex
3 u1 =
0xBE hex
4 2 bajty u2 číslo menší verze používaného formátu souboru třídy
5
6 2 bajty u2 číslo hlavní verze používaného formátu souboru třídy.

Java SE 17 = 61 (0x3D hex),
Java SE 16 = 60 (0x3C hex),
Java SE 15 = 59 (0x3B hex),
Java SE 14 = 58 (0x3A hex),
Java SE 13 = 57 (0x39 hex),
Java SE 12 = 56 (0x38 hex),
Java SE 11 = 55 (0x37 hex),
Java SE 10 = 54 (0x36 hex),
Java SE 9 = 53 (0x35 hex),
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6,0 = 50 (0x32 hex),
Java SE 5,0 = 49 (0x31 hex),
JDK 1,4 = 48 (0x30 hex),
JDK 1,3 = 47 (0x2F hex),
JDK 1,2 = 46 (0x2E hex),
JDK 1,1 = 45 (0x2D hex).
Podrobnosti o číslech dřívějších verzí najdete v poznámce pod čarou 1 v 2. vydání specifikace JavaTM Virtual Machine Specification

7
8 2 bajty u2 počet konstantních fondů, počet položek v následující tabulce konstantních fondů. 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 tabulka konstantních fondů, pole položek konstantního fondu 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í ( počet konstantních fondů - 1) celkem (viz poznámka).
...
...
...
10+ cpsize 2 bajty u2 přístupové vlajky, bitová maska
11+ cpsize
12+ cpsize 2 bajty u2 identifikuje tuto třídu, indexuje do konstantního fondu na položku typu „Třída“
13+ cpsize
14+ cpsize 2 bajty u2 identifikuje super třídu, index do konstantního fondu 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 (variabilní) stůl tabulka rozhraní: pole proměnných délek 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 (variabilní) stůl pole pole, 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 položek v následující tabulce metod
21+ cpsize + isize + fsize
22+ cpsize + isize + fsize msize (proměnná) stůl tabulka metod, řada metod s proměnnou délkou

každý prvek je struktura method_info 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 záznamů v následující tabulce atributů
23+ cpsize + isize + fsize + msize
24+ cpsize + isize + fsize + msize asize (variabilní) 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

...
...
...

Reprezentace v programovacím jazyce podobném C

Protože 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 ukázka.

struct Class_File_Format {
   u4 magic_number;

   u2 minor_version;   
   u2 major_version;

   u2 constant_pool_count;   
  
   cp_info constant_pool[constant_pool_count - 1];

   u2 access_flags;

   u2 this_class;
   u2 super_class;

   u2 interfaces_count;   
   
   u2 interfaces[interfaces_count];

   u2 fields_count;   
   field_info fields[fields_count];

   u2 methods_count;
   method_info methods[methods_count];

   u2 attributes_count;   
   attribute_info attributes[attributes_count];
}

Neustálý bazén

Tabulka konstantních fondů je místem, kde je uložena většina doslovných konstant. 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 fondů 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 fondů ve skutečnosti stejný jako počet konstantních fondů, který tabulce předchází. Za prvé, tabulka je indexována počínaje 1 (spíše než 0), ale počet by měl být ve skutečnosti interpretován jako maximální index plus jedna. Navíc dva typy konstant (dlouhé a zdvojené) zabírají dva po sobě následující 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í bajtovou značkou . Počet bajtů následujících za touto značkou a jejich interpretace pak závisí na hodnotě značky. Platné typy konstant a jejich hodnoty značek jsou:

Tag byte 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) udávající počet bajtů v kódovaném řetězci, který bezprostředně následuje (což se může lišit od počtu znaků). Všimněte si toho, že použité kódování není ve skutečnosti 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é číslo dvojky ve formátu big-endian 1.0.2
4 4 byty Float: 32bitové číslo s plovoucí desetinnou čárkou IEEE 754 s jednoduchou přesností 1.0.2
5 8 bajtů Long: podepsané 64bitové dvojkové číslo komplementu ve formátu big-endian (v konstantní kulečníkové tabulce zabere dva sloty) 1.0.2
6 8 bajtů Double: 64bitové číslo s plovoucí desetinnou čárkou IEEE 754 s dvojitou přesností (zabírá dva sloty v tabulce konstantních kulečníků) 1.0.2
7 2 bajty Odkaz na třídu: index v rámci konstantního fondu řetězce UTF-8 obsahující plně kvalifikovaný název třídy (ve vnitřním formátu ) (big-endian) 1.0.2
8 2 bajty Odkaz na řetězec: index v konstantním fondu řetězce UTF-8 (také big-endian) 1.0.2
9 4 byty Odkaz na pole: dva indexy v rámci konstantního fondu, první směřující 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 konstantního fondu, první směřující 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 konstantního fondu, první směřující 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 konstantního fondu, první představuje jméno (identifikátor) a druhý speciálně kódovaný deskriptor typu. 1.0.2
15 3 bajty Zpracování metody: tato struktura se používá k reprezentaci popisovače metod a skládá se z jednoho bajtu deskriptoru typu, za kterým následuje index v rámci konstantního fondu. 7
16 2 bajty Typ metody: tato struktura se používá k reprezentaci typu metody a skládá se z indexu v rámci konstantního fondu. 7
17 4 byty Dynamický: používá se k určení dynamicky vypočítané konstanty vytvořené vyvoláním metody bootstrap. 11
18 4 byty InvokeDynamic: toto je používáno invokedynamic instrukcí k určení metody bootstrap, názvu dynamického vyvolání, argumentu a návratových typů volání a volitelně posloupnosti dalších konstant nazývaných statické argumenty metodě bootstrap. 7
19 2 bajty Modul: slouží k identifikaci modulu. 9
20 2 bajty Balíček: slouží k identifikaci balíčku exportovaného nebo otevřeného modulem. 9

Existují pouze dva integrální typy konstant, celočíselné a dlouhé. 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ě kvalifikovány, jsou tradičně odděleny tečkami, například „java.lang.Object“. V rámci referenčních konstant nízké 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 podobný. Existují dva rozdíly ( kompletní diskusi viz UTF-8 ). První je, že kódový bod U+0000 je kódován jako dvoubajtová sekvence C0 80(v hexu) místo standardního jednobajtového kódování 00. Druhým rozdílem je, že doplňkové znaky (znaky mimo BMP při U+10 000 a výše) jsou kódovány pomocí konstrukce náhradních párů podobným UTF-16 , než aby byly přímo kódovány pomocí UTF-8. V tomto případě je každý ze dvou náhradníků kódován samostatně v UTF-8. Například U+1D11E je kódováno jako 6bajtová sekvence ED A0 B4 ED B4 9E, nikoli správné 4bajtové kódování UTF-8 F0 9D 84 9E.

Viz také

Reference

Další čtení

  • Tim Lindholm , Frank Yellin (1999). Specifikace virtuálního stroje Java (druhé vydání). Sál Prentice. ISBN 0-201-43294-3. Citováno 2008-10-13 .Oficiální definující dokument Java Virtual Machine , který obsahuje formát souboru třídy. První i druhé vydání knihy jsou volně dostupné online ke zhlédnutí a/nebo stažení .