Ohjelmointi

Java-luokan tiedostotyyli

Tervetuloa toiseen osaan "Konepellin alla". Viime kuussa julkaistussa artikkelissa keskustelin Java-virtuaalikoneesta tai JVM: stä, abstraktista tietokoneesta, jolle kaikki Java-ohjelmat on koottu. Jos et tunne JVM: ää, voit lukea viime kuukauden artikkelin ennen tätä. Tässä artikkelissa annan vilauksen Java-luokan tiedoston perusrakenteesta ja elämäntavasta.

Syntynyt matkustamaan

Java-luokan tiedosto on tarkasti määritelty muoto käännetylle Java-tiedostolle. Java-lähdekoodi kootaan luokkatiedostoiksi, jotka mikä tahansa JVM voi ladata ja suorittaa. Luokkatiedostot voivat kulkea verkon yli ennen kuin JVM lataa ne.

Itse asiassa, jos luet tätä artikkelia Java-yhteensopivan selaimen kautta, artikkelin lopussa olevat simulointisovelluksen luokan tiedostot lentävät Internetin kautta tietokoneellesi juuri nyt. Jos haluat kuunnella heitä (ja tietokoneellasi on ääniominaisuudet), paina seuraavaa painiketta:

Tarvitset Java-yhteensopivan selaimen nähdäksesi tämän sovelman

Kuulostaa siltä kuin heillä olisi hauskaa, vai mitä? Se on heidän luonteessaan. Java-luokan tiedostot on suunniteltu matkustamaan hyvin. Ne ovat alustasta riippumattomia, joten he ovat tervetulleita useampaan paikkaan. Ne sisältävät tavukoodeja, kompaktin JVM-käskyjoukon, jotta he voivat liikkua kevyesti. Java-luokan tiedostot selaavat jatkuvasti verkkoa hurjasti saavuttaakseen JVM: t kaikkialle maailmaan.

Mitä luokan tiedostossa on?

Java-luokan tiedosto sisältää kaiken, mitä JVM: n on tiedettävä yhdestä Java-luokasta tai käyttöliittymästä. Tärkeimmät komponentit ovat niiden ulkoasujärjestyksessä luokkatiedostossa: taika, versio, jatkuva pooli, pääsyliput, tämä luokka, superluokka, rajapinnat, kentät, menetelmät ja määritteet.

Luokkatiedostoon tallennetun tiedon pituus vaihtelee usein - toisin sanoen tietojen todellista pituutta ei voida ennustaa ennen luokkatiedoston lataamista. Esimerkiksi Method-komponentissa lueteltujen menetelmien määrä voi vaihdella luokkatiedostojen välillä, koska se riippuu lähdekoodissa määriteltyjen menetelmien lukumäärästä. Tällaiset tiedot on järjestetty luokkatiedostoon edeltämällä todelliset tiedot niiden koon tai pituuden mukaan. Tällä tavalla, kun JVM lataa luokkaa, muuttuvan pituisen tiedon koko luetaan ensin. Kun JVM tietää koon, se voi lukea oikeat tiedot.

Tiedot kirjoitetaan yleensä luokkatiedostoon ilman välilyöntiä tai täytettä peräkkäisten tietojen välillä; kaikki on kohdistettu tavujen rajoille. Tämä auttaa pitämään luokkatiedostot pieninä, joten ne ovat aerodynaamisia, kun ne lentävät verkon yli.

Luokkatiedostokomponenttien järjestys on määritelty tarkasti, jotta JVM: t voivat tietää, mitä odottaa ja mistä odottaa, kun luokan tiedostoa ladataan. Esimerkiksi jokainen JVM tietää, että luokkatiedoston ensimmäiset kahdeksan tavua sisältävät taikuuden ja versionumerot, että vakioalue alkaa yhdeksännestä tavusta ja että pääsyliput seuraavat vakiopoolia. Mutta koska vakioallas on vaihtelevan pituinen, se ei tiedä pääsylippujen tarkkaa sijaintia, ennen kuin se on lukenut vakiopoolissa. Kun se on lukenut vakiopoolissa, se tietää, että seuraavat kaksi tavua ovat pääsyliput.

Taika- ja versionumerot

Jokaisen luokkatiedoston neljä ensimmäistä tavua ovat aina 0xCAFEBABE. Tämä maaginen numero tekee Java-luokan tiedostoista helpommin tunnistettavissa, koska kertoimet ovat vähäiset siitä, että ei-luokan tiedostot alkavat samoilla neljällä tavulla. Numeroa kutsutaan taikuudeksi, koska tiedostomuodon suunnittelijat voivat vetää sen hatusta. Ainoa vaatimus on, että sitä ei jo käytetä toisessa tiedostomuodossa, jota voi esiintyä todellisessa maailmassa. Alkuperäisen Java-tiimin avainjäsenen Patrick Naughtonin mukaan maaginen numero valittiin "kauan ennen kuin Java-nimi oli koskaan lausuttu viitaten tähän kieleen. Etsimme jotain hauskaa, ainutlaatuista ja helposti muistettavaa. Se on vain sattuma, että OxCAFEBABE, viisto viittaus Peet's Coffee -söpöihin baristoihin, ennakoi Java-nimeä. "

Luokkatiedoston neljä toista tavua sisältävät pää- ja ala-versionumerot. Nämä numerot tunnistavat sen luokan tiedostomuodon version, jota tietty luokkatiedosto noudattaa, ja antavat JVM: ien tarkistaa, että luokkatiedosto on ladattavissa. Jokaisella JVM: llä on maksimiversio, jonka se voi ladata, ja JVM: t hylkäävät luokkatiedostot uudemmilla versioilla.

Jatkuva uima-allas

Luokkatiedosto tallentaa luokkaan tai käyttöliittymään liittyvät vakiot vakiopooliin. Jotkut vakiot, jotka voidaan nähdä möllivän poolissa, ovat kirjaimellisia merkkijonoja, lopulliset muuttujien arvot, luokkien nimet, käyttöliittymien nimet, muuttujien nimet ja tyypit sekä menetelmien nimet ja allekirjoitukset. Menetelmä allekirjoitus on sen palautustyyppi ja joukko argumenttityyppejä.

Vakioallas on järjestetty vaihtelevan pituisten elementtien joukoksi. Jokainen vakio vie yhden elementin taulukossa. Koko luokkatiedostossa vakioihin viitataan kokonaislukuindeksillä, joka osoittaa niiden sijainnin taulukossa. Alkuperäisen vakion indeksi on yksi, toisen vakion indeksi on kaksi jne. Vakio pooliryhmää edeltää sen matriisikoko, joten JVM: t tietävät, kuinka monta vakiota luokkatiedostoa ladattaessa voidaan odottaa.

Kukin vakiopoolin elementti alkaa yksitavuisella tagilla, joka määrittää vakion tyypin taulukon tässä kohdassa. Kun JVM tarttuu ja tulkitsee tämän tunnisteen, se tietää, mitä tagia seuraa. Esimerkiksi, jos tagi osoittaa, että vakio on merkkijono, JVM odottaa seuraavien kahden tavun olevan merkkijonon pituus. Tämän kahden tavun pituuden jälkeen JVM odottaa löytävänsä pituus tavujen lukumäärä, jotka muodostavat merkkijonon merkit.

Artikkelin loppuosassa viittaan joskus vakio pooliryhmän n. Elementtiin vakiona_pooli [n]. Tämä on järkevää siinä määrin kuin vakiopooli on järjestetty matriisin tavoin, mutta pidä mielessä, että näillä elementeillä on erikokoiset ja -tyypit ja että ensimmäisen elementin indeksi on yksi.

Käytä lippuja

Kaksi ensimmäistä tavua vakiopoolin jälkeen, pääsyliput, ilmoittavat, määritteleekö tämä tiedosto luokan tai käyttöliittymän, onko luokka tai käyttöliittymä julkinen vai abstrakti, ja (jos se on luokka eikä käyttöliittymä), onko luokka on lopullinen.

Tämä luokka

Seuraavat kaksi tavua, Tämä luokka komponentti, ovat hakemisto vakiosarjaryhmään. Vakio, johon viitataan Tämä luokka, vakio_pooli [tämä_luokka], on kaksi osaa, yksi- ja kaksitavuinen nimiindeksi. Tunniste on yhtä suuri kuin CONSTANT_Class, arvo, joka osoittaa, että tämä elementti sisältää tietoja luokasta tai käyttöliittymästä. Vakio_pooli [nimi_indeksi] on merkkivakio, joka sisältää luokan tai käyttöliittymän nimen.

Tämä luokka komponentti antaa vilauksen vakiopoolin käytöstä. Tämä luokka itsessään on vain indeksi vakiopooliin. Kun JVM etsii vakiona_pooli [tämä_luokka], se löytää elementin, joka identifioi itsensä VAKIONAISEKSI luokkana taginsa kanssa. JVM tietää, että CONSTANT_Class-elementeillä on aina kaksitavuinen hakemisto vakioalueeseen, nimeltään nimiindeksi, yhden tavun taginsa jälkeen. Joten se etsii vakio_pooli [nimi_indeksi] saadakseen merkkijonon, joka sisältää luokan tai käyttöliittymän nimen.

Superluokka

Seuraamalla Tämä luokka komponentti on superluokka komponentti, toinen kaksitavuinen indeksi vakiopooliin. Constant_pool [super_class] on CONSTANT_Class-elementti, joka osoittaa sen superluokan nimen, josta tämä luokka laskeutuu.

Liitännät

Rajapintakomponentti alkaa tiedostossa määritetyn luokan (tai käyttöliittymän) toteuttamien rajapintojen määrän kaksitavuisella lukumäärällä. Heti seuraa taulukko, joka sisältää yhden hakemiston vakiopooliin kutakin luokan toteuttamaa rajapintaa varten. Kutakin käyttöliittymää edustaa CONSTANT_Class-elementti vakioalueessa, joka osoittaa käyttöliittymän nimeä.

Kentät

Kenttäkomponentti alkaa kaksitavuisella tämän luokan tai käyttöliittymän kenttien lukumäärällä. Kenttä on luokan tai rajapinnan esiintymä tai luokan muuttuja. Laskurin jälkeen on joukko vaihtelevan pituisia rakenteita, yksi kullekin kentälle. Kukin rakenne paljastaa tietoja yhdestä kentästä, kuten kentän nimen, tyypin ja, jos se on lopullinen muuttuja, sen vakioarvon. Jotkut tiedot sisältyvät itse rakenteeseen ja osa sisältyvät vakioihin allasosastoihin, joihin rakenne viittaa.

Ainoat luettelossa näkyvät kentät ovat kentät, jotka ilmoitti tiedostossa määritelty luokka tai käyttöliittymä; yhtään superluokista tai superliitännöistä perittyjä kenttiä ei näy luettelossa.

Menetelmät

Metodikomponentti alkaa luokan tai rajapinnan menetelmien määrän kaksitavuisella lukumäärällä. Laskenta sisältää vain ne menetelmät, jotka tämä luokka on nimenomaisesti määrittänyt, ei menetelmiä, jotka voidaan periä yläluokista. Menetelmien laskemisen seuraaminen on itse menetelmiä.

Kunkin menetelmän rakenne sisältää useita tietoja menetelmästä, mukaan lukien menetelmän kuvaus (sen palautustyyppi ja argumenttiluettelo), menetelmän paikallisiin muuttujiin tarvittavan pinon sanojen lukumäärän, menetelmän operandille tarvittavan pinon sanojen enimmäismäärän pino, taulukko menetelmän saamista poikkeuksista, tavukoodisekvenssi ja rivinumerotaulukko.

Määritteet

Takana ovat attribuutit, jotka antavat yleistä tietoa tiedoston määrittelemästä luokasta tai käyttöliittymästä. Määritteet-osiossa on kaksitavuinen määrämäärien määrä, jota seuraavat itse määritteet. Esimerkiksi yksi attribuutti on lähdekoodimäärite; se paljastaa lähdetiedoston nimen, josta tämä luokkatiedosto on koottu. JVM: t jättävät huomiotta kaikki attribuutit, joita he eivät tunnista.

Ladataan: luokkatiedoston simulaatio, joka saavuttaa JVM-määränpään

Alla oleva sovelma simuloi JVM: ää luokkatiedoston lataamisessa. Simulaatioon ladattava luokkatiedosto luotiin javac-kääntäjällä, joka antoi seuraavan Java-lähdekoodin:

luokka Act {public static void doMathForever () {int i = 0; kun (tosi) {i + = 1; i * = 2; }}} 

Yllä oleva koodinpätkä on peräisin viime kuukauden JVM: ää käsittelevästä artikkelista. Se on sama doMathForever () -menetelmä, jonka EternalMath-sovelma suoritti viime kuukauden artikkelista. Valitsin tämän koodin tarjotakseni todellisen esimerkin, joka ei ollut liian monimutkainen. Vaikka koodi ei ehkä ole kovin hyödyllinen todellisessa maailmassa, se kääntyy todelliseksi luokkatiedostoksi, jonka alla oleva simulaatio lataa.

GettingLoaded-sovelman avulla voit ajaa luokan kuormitussimulaatiota yksi askel kerrallaan. Jokaisesta askeleesta matkan varrella voit lukea seuraavan tavunpalan, jonka JVM aikoo kuluttaa ja tulkita. Paina vain "Vaihe" -painiketta saadaksesi JVM: n kuluttamaan seuraavan palan. "Takaisin" -näppäimen painaminen peruu edellisen vaiheen, ja "Palauta" -näppäimen painaminen palauttaa simulaation alkuperäiseen tilaansa, jolloin voit aloittaa alusta.

JVM näkyy vasemmassa alakulmassa kuluttamalla tavuvirtaa, joka muodostaa luokkatiedoston Act.class. Tavut näytetään heksasiirtona palvelimesta oikeassa alakulmassa. Tavut kulkevat oikealta vasemmalle, palvelimen ja JVM: n välillä, yksi kappale kerrallaan. Paljon tavuja, jotka JVM kuluttaa seuraavalla "Step" -painikkeen painalluksella, näkyvät punaisina. Nämä korostetut tavut kuvataan suurella tekstialueella JVM: n yläpuolella. Seuraavan kappaleen jälkeen jäljellä olevat tavut näytetään mustalla.

Olen yrittänyt selittää jokaisen tavunpalan tekstialueella. Siksi tekstialueella on paljon yksityiskohtia, ja haluat ehkä selata kaikki vaiheet ensin saadaksesi yleisen idean, ja katso sitten lisätietoja.

Hyvää napsautusta.

Tarvitset Java-yhteensopivan selaimen nähdäksesi tämän sovelman.

Napsauta tätä saadaksesi GettingLoaded-lähdekoodin. Jos haluat suorittaa tämän sovelman yksin, tarvitset myös kaksi tiedostoa, jotka tämä sovelma noutaa palvelimelta, ASCII-tiedoston, joka sisältää kunkin vaiheen tekstin, ja itse Act.class-tiedoston. Napsauta tätä saadaksesi Flying Class Files -äänisovelluksen lähdekoodin.

LOPPU: Pieni paino: "Java-luokan tiedostojen elämäntapa" -artikkeli Copyright (c) 1996 Bill Venners. Kaikki oikeudet pidätetään. "GettingLoaded" -sovellus Tekijänoikeus (c) 1996 Artima Software Company. Kaikki oikeudet pidätetään.

: END_ENDNOTE

Bill Venners on Artima Software Companyn toimitusjohtaja. Artiman kautta hän tekee räätälöityjä ohjelmistokehityksiä ja konsultointia.

Lisätietoja tästä aiheesta

  • Java Virtual Machine Specification, Sunin virallinen sana.

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

  • Kun se ilmestyy, kirja Java-virtuaalikoneiden määrittely, //www.aw.com/cp/lindholm-yellin.html, Tim Lindholm ja Frank Yellin (ISBN 0-201-63452-X), osa Java-sarjaa, //www.aw.com/cp/ javaseries.html), Addison-Wesley, on todennäköisesti paras JVM-resurssi.
  • Luonnos Java-virtuaalikoneiden määrittely, joka kuvaa luokan tiedostomuodon ja tavukoodin vahvistimen, voidaan noutaa JavaSoftista.

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

Tämän tarinan "Java-luokan tiedostotyyli" julkaisi alun perin JavaWorld.