Programmering

Java-klassens filstil

Velkommen til endnu en del af "Under hætten." I sidste måneds artikel diskuterede jeg Java Virtual Machine eller JVM, den abstrakte computer, som alle Java-programmer er samlet til. Hvis du ikke er bekendt med JVM, kan du læse artiklen fra sidste måned før denne. I denne artikel giver jeg et indblik i den grundlæggende struktur og livsstil i Java-klassefilen.

Født til at rejse

Java-klassefilen er et nøjagtigt defineret format til kompileret Java. Java-kildekode er sammensat til klassefiler, der kan indlæses og udføres af enhver JVM. Klassefilerne rejser muligvis over et netværk, før de indlæses af JVM.

Faktisk, hvis du læser denne artikel via en Java-kompatibel browser, flyver klassefiler til simuleringsapplet i slutningen af ​​artiklen over internettet til din computer lige nu. Hvis du gerne vil lytte ind på dem (og din computer har lydfunktion), skal du trykke på følgende knap:

Du har brug for en Java-aktiveret browser for at se denne applet

Det lyder som om de har det sjovt, ikke? Det er i deres natur. Java-klassefiler blev designet til at rejse godt. De er platformuafhængige, så de vil være velkomne flere steder. De indeholder bytekoder, det kompakte instruktions sæt til JVM, så de kan rejse let. Java-klassefiler lynlåser konstant gennem netværk i en voldsom hastighed for at nå frem til JVM'er over hele verden.

Hvad er der i en klassefil?

Java-klassefilen indeholder alt, hvad en JVM har brug for at vide om en Java-klasse eller interface. I deres rækkefølge af udseende i klassefilen er de vigtigste komponenter: magi, version, konstant pool, adgangsflag, denne klasse, superklasse, grænseflader, felter, metoder og attributter.

Oplysninger, der er gemt i klassefilen, varierer ofte i længde - det vil sige, at informationens faktiske længde ikke kan forudsiges, før klassefilen indlæses. For eksempel kan antallet af metoder, der er anført i metodekomponenten, variere mellem klassefiler, fordi det afhænger af antallet af metoder, der er defineret i kildekoden. Sådan information er organiseret i klassefilen ved at placere den aktuelle information i stedet for dens størrelse eller længde. På denne måde, når klassen indlæses af JVM, læses størrelsen på information med variabel længde først. Når JVM kender størrelsen, kan den korrekt læse i de faktiske oplysninger.

Information skrives generelt til klassefilen uden mellemrum eller polstring mellem på hinanden følgende informationstykker; alt er tilpasset bytegrænser. Dette hjælper med at holde klassefiler petite, så de bliver aerodynamiske, når de flyver på tværs af netværk.

Rækkefølgen af ​​klassefilkomponenter er strengt defineret, så JVM'er kan vide, hvad de kan forvente, og hvor de kan forvente, når de indlæser en klassefil. For eksempel ved enhver JVM, at de første otte byte i en klassefil indeholder magiske og versionsnumre, at den konstante pool starter på den niende byte, og at adgangsflagene følger den konstante pool. Men fordi den konstante pool er variabel længde, ved den ikke den nøjagtige placering af adgangsflagene, før den er færdig med at læse i den konstante pool. Når den er færdig med at læse i den konstante pool, ved den, at de næste to byte vil være adgangsflagene.

Magiske og versionsnumre

De første fire byte i hver klassefil er altid 0xCAFEBABE. Dette magiske nummer gør Java-klassefiler lettere at identificere, fordi oddsene er små, at filer, der ikke er i klasse, starter med de samme fire første byte. Nummeret kaldes magi, fordi det kan trækkes op af en hat af filformatdesignerne. Det eneste krav er, at det ikke allerede bruges af et andet filformat, der kan forekomme i den virkelige verden. Ifølge Patrick Naughton, et nøglemedlem i det oprindelige Java-team, blev det magiske nummer valgt "længe før navnet Java nogensinde blev sagt med henvisning til dette sprog. Vi ledte efter noget sjovt, unikt og let at huske. Det er kun en tilfældighed, at OxCAFEBABE, en skrå henvisning til de søde baristas ved Peet's Coffee, var en forudskue for navnet Java. "

De anden fire byte i klassefilen indeholder hoved- og mindre versionnumre. Disse tal identificerer den version af klassefilformatet, som en bestemt klassefil overholder, og tillader JVM'er at kontrollere, at klassefilen kan indlæses. Hver JVM har den maksimale version, den kan indlæse, og JVM'er afviser klassefiler med senere versioner.

Konstant pool

Klassefilen gemmer konstanter tilknyttet sin klasse eller grænseflade i den konstante pool. Nogle konstanter, der kan ses i poolen, er bogstavelige strenge, endelige variabelværdier, klassenavne, interfacenavne, variabelnavne og -typer samt metodenavne og signaturer. En metode Underskrift er returtypen og sæt af argumenttyper.

Den konstante pool er organiseret som en række elementer med variabel længde. Hver konstant optager et element i arrayet. I hele klassefilen henvises til konstanter ved det heltalsindeks, der angiver deres position i arrayet. Den oprindelige konstant har et indeks på en, den anden konstant har et indeks på to osv. Den konstante pool-array er forud for dens array-størrelse, så JVM'er ved, hvor mange konstanter de kan forvente, når de indlæser klassefilen.

Hvert element i den konstante pool begynder med et tag på en byte, der angiver typen af ​​konstant på den position i arrayet. Når en JVM griber og fortolker dette tag, ved det, hvad der følger tagget. For eksempel, hvis et mærke angiver, at konstanten er en streng, forventer JVM, at de næste to byte er strenglængden. Efter denne to-byte længde forventer JVM at finde længde antal bytes, der udgør tegnene i strengen.

I den resterende del af artiklen henviser jeg undertiden til det nte element i den konstante pool-array som constant_pool [n]. Dette giver mening i det omfang den konstante pool er organiseret som en matrix, men husk at disse elementer har forskellige størrelser og typer, og at det første element har et indeks på et.

Adgang til flag

De første to byte efter den konstante pool, adgangsflagene, angiver, om denne fil definerer en klasse eller en grænseflade, om klassen eller grænsefladen er offentlig eller abstrakt, og (hvis det er en klasse og ikke en grænseflade) om klassen er endelig.

Denne klasse

De næste to bytes, den denne klasse komponent, er et indeks i det konstante puljearray. Den konstant, der er omtalt af denne klasse, constant_pool [denne_klasse], har to dele, et en-byte-tag og et to-byte-navneindeks. Tagget svarer til CONSTANT_Class, en værdi, der angiver, at dette element indeholder oplysninger om en klasse eller grænseflade. Constant_pool [name_index] er en strengkonstant, der indeholder navnet på klassen eller grænsefladen.

Det denne klasse komponent giver et glimt af, hvordan den konstante pool bruges. Denne klasse i sig selv er bare et indeks i den konstante pulje. Når en JVM ser konstant_pool [denne_klasse] op, finder den et element, der identificerer sig selv som en CONSTANT_Class med sit tag. JVM ved, at CONSTANT_Class-elementer altid har et to-byte-indeks i den konstante pool, kaldet navneindeks, efter deres en-byte-tag. Så det ser op konstant_pool [navn_index] for at få strengen, der indeholder navnet på klassen eller grænsefladen.

Super klasse

Efter denne klasse komponenten er super klasse komponent, endnu et to-byte-indeks i den konstante pool. Constant_pool [superklasse] er et CONSTANT_Class-element, der peger på navnet på den superklasse, hvorfra denne klasse stammer.

Grænseflader

Interfacekomponenten starter med et to-byte-antal af antallet af interfaces implementeret af den klasse (eller interface), der er defineret i filen. Umiddelbart efter er en matrix, der indeholder et indeks i den konstante pool for hver grænseflade implementeret af klassen. Hver grænseflade er repræsenteret af et CONSTANT_Class-element i den konstante pool, der peger på navnet på grænsefladen.

Felter

Feltekomponenten starter med et antal to byte af antallet af felter i denne klasse eller grænseflade. Et felt er en forekomst eller klassevariabel af klassen eller grænsefladen. Efter optællingen findes en række strukturer med variabel længde, en for hvert felt. Hver struktur afslører oplysninger om et felt, såsom feltets navn, type, og hvis det er en endelig variabel, dets konstante værdi. Nogle oplysninger er indeholdt i selve strukturen, og nogle er indeholdt i konstante poolplaceringer, som strukturen peger på.

De eneste felter, der vises på listen, er dem, der blev erklæret af den klasse eller grænseflade, der er defineret i filen; ingen felter arvet fra superklasser eller superinterfaces vises på listen.

Metoder

Metodekomponenten starter med et to-byte-antal af antallet af metoder i klassen eller grænsefladen. Denne optælling inkluderer kun de metoder, der udtrykkeligt er defineret af denne klasse, ikke nogen metoder, der kan nedarves fra superklasser. Efter metodetællingen er metoderne selv.

Strukturen for hver metode indeholder flere stykker information om metoden, herunder metodebeskrivelsen (dens returtype og argumentlisten), antallet af stakord, der kræves for metodens lokale variabler, det maksimale antal stakord, der kræves for metoden operand stak, en tabel med undtagelser fanget af metoden, bytecode-sekvensen og en linjenummertabel.

Egenskaber

At bringe bagud er attributterne, som giver generel information om den bestemte klasse eller grænseflade, der er defineret af filen. Attributtsektionen har et to-byte antal af attributter efterfulgt af selve attributterne. For eksempel er en attribut kildekodeattributten; det afslører navnet på den kildefil, hvorfra denne klassefil blev kompileret. JVM'er ignorerer lydløst alle attributter, de ikke genkender.

Sådan indlæses: en simulering af en klassefil, der når sin JVM-destination

Applet'en nedenfor simulerer en JVM, der indlæser en klassefil. Klassefilen, der indlæses i simuleringen, blev genereret af javac-kompilatoren givet følgende Java-kildekode:

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

Ovenstående kodestykke kommer fra sidste måneds artikel om JVM. Det er den samme doMathForever () -metode, der udføres af EternalMath-appleten fra sidste måneds artikel. Jeg valgte denne kode for at give et rigtigt eksempel, der ikke var for kompliceret. Selvom koden muligvis ikke er særlig nyttig i den virkelige verden, kompileres den til en rigtig klassefil, der indlæses af nedenstående simulering.

GettingLoaded-appleten giver dig mulighed for at køre klassebelastningssimulering et trin ad gangen. For hvert trin undervejs kan du læse om det næste stykke byte, der er ved at blive fortæret og fortolket af JVM. Bare tryk på "Trin" -knappen for at få JVM til at forbruge det næste stykke. Ved at trykke på "Tilbage" fortrydes det foregående trin, og ved at trykke på "Nulstil" vil simuleringen vende tilbage til sin oprindelige tilstand, så du kan starte forfra fra starten.

JVM vises nederst til venstre og forbruger strømmen af ​​bytes, der udgør klassefilen Act.class. Bytes vises i hex-streaming ud af en server nederst til højre. Bytes kører højre mod venstre mellem serveren og JVM, en del ad gangen. Den bit byte, der skal forbruges af JVM ved næste tryk på "Step" -knappen, vises med rødt. Disse fremhævede bytes er beskrevet i det store tekstområde over JVM. Eventuelle resterende bytes udover det næste stykke vises i sort.

Jeg har forsøgt at forklare fuldstændigt hvert stykke byte i tekstområdet. Der er derfor mange detaljer i tekstområdet, og du vil muligvis først gennemse alle trin for at få den generelle idé, og se derefter tilbage for at få flere detaljer.

Glad klik.

Du har brug for en Java-aktiveret browser for at se denne applet.

Klik her for kildekoden til GettingLoaded. For at køre denne applet alene, skal du også bruge de to filer, som denne applet henter fra serveren, ASCII-filen, der indeholder teksten for hvert trin, og selve Act.class-filen. Klik her for kildekoden til Flying Class Files-lydapplet.

BEMÆRKNING: Det med småt: "The Java Class File Lifestyle" Artikel Copyright (c) 1996 Bill Venners. Alle rettigheder forbeholdes. "GettingLoaded" Applet Copyright (c) 1996 Artima Software Company. Alle rettigheder forbeholdes.

: END_ENDBEMÆRK

Bill Venners er præsident for Artima Software Company. Gennem Artima laver han brugerdefineret softwareudvikling og rådgivning.

Lær mere om dette emne

  • Java Virtual Machine Specification, det officielle ord fra Sun.

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

  • Når det kommer ud, bogen Java Virtual Machine Specification, //www.aw.com/cp/lindholm-yellin.html, af Tim Lindholm og Frank Yellin (ISBN 0-201-63452-X), en del af Java-serien, //www.aw.com/cp/ javaseries.html), fra Addison-Wesley, vil sandsynligvis være den bedste JVM-ressource.
  • Et udkast til kapitel 4 af Specifikationen for Java Virtual Machine, som beskriver klasse-filformat og bytecode-verifikator, kan hentes fra JavaSoft.

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

Denne historie, "The Java class file lifestyle" blev oprindeligt udgivet af JavaWorld.

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