File di classe Java - Java class file

File di classe Java
Tipo di media Internet application/java-vm, application/x-httpd-java
Sviluppato da Microsistemi solari

Un file di classe Java è un file (con l' estensione del nome file .class ) contenente il bytecode Java che può essere eseguito sulla Java Virtual Machine (JVM) . Un file di classe Java viene solitamente prodotto da un compilatore Java da file sorgente del linguaggio di programmazione Java ( file .java ) contenenti classi Java (in alternativa, è possibile utilizzare anche altri linguaggi JVM per creare file di classe). Se un file sorgente ha più di una classe, ogni classe viene compilata in un file di classe separato.

Le JVM sono disponibili per molte piattaforme e un file di classe compilato su una piattaforma verrà eseguito su una JVM di un'altra piattaforma. Ciò rende le applicazioni Java indipendenti dalla piattaforma .

Storia

L'11 dicembre 2006, il formato del file di classe è stato modificato in Java Specification Request (JSR) 202.

Layout e struttura del file

Sezioni

Ci sono 10 sezioni di base per la struttura del file di classe Java:

  • Numero magico : 0xCAFEBABE
  • Versione del formato file di classe : le versioni minore e principale del file di classe
  • Constant Pool : Pool di costanti per la classe
  • Flag di accesso : ad esempio se la classe è astratta, statica, ecc.
  • Questa classe : il nome della classe corrente
  • Super classe : il nome della super classe
  • Interfacce : tutte le interfacce della classe
  • Campi : tutti i campi della classe
  • Metodi : tutti i metodi della classe
  • Attributi : qualsiasi attributo della classe (ad esempio il nome del file sorgente, ecc.)

Numero magico

I file di classe sono identificati dalla seguente intestazione di 4 byte (in esadecimale ): (le prime 4 voci nella tabella seguente). La storia di questo numero magico è stata spiegata da James Gosling riferendosi ad un ristorante di Palo Alto : CA FE BA BE

"Andavamo a pranzo in un posto chiamato St Michael's Alley. Secondo la leggenda locale, nel profondo oscuro passato, i Grateful Dead si esibivano lì prima che diventassero grandi. Era un posto piuttosto funky che era sicuramente un Grateful Dead Kinda Place. Quando Jerry è morto, hanno persino messo su un piccolo santuario in stile buddista. Quando andavamo lì, ci riferivamo al posto come Cafe Dead. Da qualche parte lungo la linea si è notato che questo era un numero esadecimale. I stava rinnovando il codice del formato file e aveva bisogno di un paio di numeri magici : uno per il file oggetto persistente e uno per le classi.Ho usato CAFEDEAD per il formato del file oggetto e in grepping per le parole esadecimali di 4 caratteri che si adattano dopo "CAFE " (sembrava essere un buon tema) mi sono imbattuto in BABE e ho deciso di usarlo. A quel tempo, non sembrava molto importante o destinato ad andare da nessuna parte tranne che nel cestino della storia. Quindi CAFEBABE è diventato il file di classe format e CAFEDEAD era il formato oggetto persistente, ma la funzione oggetto persistente andò a rotoli sì, e con esso è andato l'uso di CAFEDEAD - alla fine è stato sostituito da RMI .

Layout generale

Poiché il file di classe contiene elementi di dimensioni variabili e non contiene anche offset di file incorporati (o puntatori), viene in genere analizzato in sequenza, dal primo byte verso la fine. Al livello più basso il formato del file è descritto in termini di alcuni tipi di dati fondamentali:

  • u1 : un intero senza segno a 8 bit
  • u2 : un intero senza segno a 16 bit nell'ordine dei byte big-endian
  • u4 : un intero senza segno a 32 bit nell'ordine dei byte big-endian
  • table : un array di elementi di lunghezza variabile di qualche tipo. Il numero di elementi nella tabella è identificato da un numero di conteggio precedente (il conteggio è u2), ma la dimensione in byte della tabella può essere determinata solo esaminando ciascuno dei suoi elementi.

Alcuni di questi tipi fondamentali vengono quindi reinterpretati come valori di livello superiore (come stringhe o numeri in virgola mobile), a seconda del contesto. Non c'è l'imposizione dell'allineamento delle parole, quindi non vengono mai utilizzati byte di riempimento. Il layout generale del file di classe è come mostrato nella tabella seguente.

byte offset dimensione tipo o valore descrizione
0 4 byte
u1 = 0xCA esadecimale
numero magico (CAFEBABE) utilizzato per identificare il file come conforme al formato del file di classe
1 u1 =
0xFE esadecimale
2
u1 = 0xBA esadecimale
3
u1 = 0xBE esadecimale
4 2 byte u2 numero di versione minore del formato di file di classe utilizzato
5
6 2 byte u2 numero di versione principale del formato di file di classe utilizzato.

Java SE 17 = 61 (0x3D esadecimale),
Java SE 16 = 60 (0x3C esadecimale),
Java SE 15 = 59 (0x3B esadecimale),
Java SE 14 = 58 (0x3A esadecimale),
Java SE 13 = 57 (0x39 esadecimale),
Java SE 12 = 56 (0x38 esadecimale),
Java SE 11 = 55 (0x37 esadecimale),
Java SE 10 = 54 (0x36 esadecimale),
Java SE 9 = 53 (0x35 esadecimale),
Java SE 8 = 52 (0x34 esadecimale),
Java SE 7 = 51 (0x33 esadecimale),
Java SE 6.0 = 50 (0x32 esadecimale),
Java SE 5.0 = 49 (0x31 esadecimale),
JDK 1.4 = 48 (0x30 esadecimale),
JDK 1.3 = 47 (0x2F esadecimale),
JDK 1.2 = 46 (0x2E esadecimale),
JDK 1.1 = 45 (0x2D esadecimale).
Per i dettagli sui numeri delle versioni precedenti, vedere la nota 1 in The JavaTM Virtual Machine Specification 2a edizione

7
8 2 byte u2 conteggio pool costante, numero di voci nella seguente tabella pool costante. Questo conteggio è almeno uno maggiore del numero effettivo di voci; vedere la seguente discussione.
9
10 cpssize (variabile) tavolo tabella del pool costante, un array di voci del pool costante di dimensioni variabili, contenente elementi come numeri letterali, stringhe e riferimenti a classi o metodi. Indicizzato a partire da 1, contenente ( conteggio pool costante - 1) numero di voci in totale (vedi nota).
...
...
...
10+ cpssize 2 byte u2 flag di accesso, una maschera di bit
11+ cps
12+ cps 2 byte u2 identifica questa classe, indicizza nel pool costante a una voce di tipo "Classe"
13+ cps
14+ cps 2 byte u2 identifica la super classe, indicizza nel pool costante a una voce di tipo "Classe"
15+ cps
16+ cps 2 byte u2 conteggio interfaccia, numero di voci nella seguente tabella interfaccia
17+ cps
18+ cps dimensione (variabile) tavolo tabella delle interfacce: un array a lunghezza variabile di indici di pool costanti che descrivono le interfacce implementate da questa classe
...
...
...
18+ cpssize + isize 2 byte u2 conteggio dei campi, numero di voci nella seguente tabella dei campi
19+ cpssize + isize
20+ cpssize + isize fsize (variabile) tavolo tabella dei campi, array di campi a lunghezza variabile

ogni elemento è una struttura field_info definita in https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5

...
...
...
20+ cpssize + isize + fsize 2 byte u2 conteggio del metodo, numero di voci nella seguente tabella dei metodi
21+ cpssize + isize + fsize
22+ cpssize + isize + fsize msize (variabile) tavolo tabella dei metodi, array di metodi a lunghezza variabile

ogni elemento è una struttura method_info definita in https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6

...
...
...
22+ cpssize + isize + fsize + msize 2 byte u2 conteggio degli attributi, numero di voci nella seguente tabella degli attributi
23+ cpssize + isize + fsize + msize
24+ cpssize + isize + fsize + msize dimensione (variabile) tavolo tabella degli attributi, array di attributi a lunghezza variabile

ogni elemento è una struttura attribute_info definita in https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7

...
...
...

Rappresentazione in un linguaggio di programmazione simile al C

Poiché C non supporta più array di lunghezza variabile all'interno di una struttura, il codice seguente non verrà compilato e funge solo da dimostrazione.

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];
}

La piscina costante

Il tavolo da biliardo costante è il punto in cui viene archiviata la maggior parte dei valori costanti letterali. Ciò include valori come numeri di tutti i tipi, stringhe, nomi di identificatori, riferimenti a classi e metodi e descrittori di tipo. Tutti gli indici, o riferimenti, a costanti specifiche nella tabella del pool di costanti sono dati da numeri a 16 bit (tipo u2), dove il valore dell'indice 1 si riferisce alla prima costante nella tabella (il valore dell'indice 0 non è valido).

A causa delle scelte storiche effettuate durante lo sviluppo del formato file, il numero di costanti nella tabella del pool costante non è in realtà lo stesso del conteggio del pool costante che precede la tabella. Innanzitutto, la tabella viene indicizzata a partire da 1 (anziché da 0), ma il conteggio deve essere effettivamente interpretato come l'indice massimo più uno. Inoltre, due tipi di costanti (long e double) occupano due slot consecutivi nella tabella, sebbene il secondo di tali slot sia un indice fantasma che non viene mai utilizzato direttamente.

Il tipo di ogni elemento (costante) nel pool di costanti è identificato da un tag byte iniziale . Il numero di byte che seguono questo tag e la loro interpretazione dipendono quindi dal valore del tag. I tipi di costanti validi e i loro valori di tag sono:

Tagga byte Byte aggiuntivi Descrizione della costante Versione introdotta
1 2+ x byte
(variabile)
Stringa UTF-8 (Unicode): una stringa di caratteri preceduta da un numero a 16 bit (tipo u2) che indica il numero di byte nella stringa codificata che segue immediatamente (che può essere diverso dal numero di caratteri). Si noti che la codifica utilizzata non è effettivamente UTF-8 , ma comporta una leggera modifica del modulo di codifica standard Unicode. 1.0.2
3 4 byte Intero: un numero in complemento a due a 32 bit con segno in formato big-endian 1.0.2
4 4 byte Float: un numero a virgola mobile IEEE 754 a precisione singola a 32 bit 1.0.2
5 8 byte Long: un numero in complemento a due a 64 bit con segno in formato big-endian (occupa due slot nel tavolo da biliardo costante) 1.0.2
6 8 byte Double: un numero a virgola mobile IEEE 754 a doppia precisione a 64 bit (occupa due slot nel tavolo da biliardo costante) 1.0.2
7 2 byte Riferimento classe: un indice all'interno del pool di costanti a una stringa UTF-8 contenente il nome completo della classe (in formato interno ) (big-endian) 1.0.2
8 2 byte Riferimento stringa: un indice all'interno del pool costante a una stringa UTF-8 (anche big-endian) 1.0.2
9 4 byte Riferimento campo: due indici all'interno del pool di costanti, il primo che punta a un riferimento Class, il secondo a un descrittore Name e Type. (big endian) 1.0.2
10 4 byte Riferimento al metodo: due indici all'interno del pool di costanti, il primo che punta a un riferimento Class, il secondo a un descrittore Name e Type. (big endian) 1.0.2
11 4 byte Riferimento al metodo dell'interfaccia: due indici all'interno del pool di costanti, il primo che punta a un riferimento Class, il secondo a un descrittore Name e Type. (big endian) 1.0.2
12 4 byte Nome e descrittore di tipo: due indici di stringhe UTF-8 all'interno del pool di costanti, il primo che rappresenta un nome (identificatore) e il secondo un descrittore di tipo appositamente codificato. 1.0.2
15 3 byte Handle del metodo: questa struttura viene utilizzata per rappresentare un handle del metodo e consiste in un byte del descrittore di tipo, seguito da un indice all'interno del pool di costanti. 7
16 2 byte Tipo di metodo: questa struttura viene utilizzata per rappresentare un tipo di metodo e consiste in un indice all'interno del pool di costanti. 7
17 4 byte Dinamico: viene utilizzato per specificare una costante calcolata dinamicamente prodotta dall'invocazione di un metodo bootstrap. 11
18 4 byte InvokeDynamic: viene utilizzato da un'istruzione invokedynamic per specificare un metodo bootstrap, il nome dell'invocazione dinamica, l'argomento e i tipi restituiti della chiamata e, facoltativamente, una sequenza di costanti aggiuntive chiamate argomenti statici per il metodo bootstrap. 7
19 2 byte Modulo: serve per identificare un modulo. 9
20 2 byte Pacchetto: viene utilizzato per identificare un pacchetto esportato o aperto da un modulo. 9

Esistono solo due tipi di costanti integrali, intero e lungo. Altri tipi integrali che compaiono nel linguaggio di alto livello, come boolean, byte e short, devono essere rappresentati come una costante intera.

I nomi delle classi in Java, quando sono completamente qualificati, sono tradizionalmente separati da punti, come "java.lang.Object". Tuttavia, all'interno delle costanti di riferimento Class di basso livello, viene visualizzato un modulo interno che utilizza invece le barre, come "java/lang/Object".

Le stringhe Unicode, nonostante il moniker "stringa UTF-8", non sono effettivamente codificate secondo lo standard Unicode, sebbene sia simile. Ci sono due differenze (vedi UTF-8 per una discussione completa). Il primo è che il punto di codice U+0000 è codificato come sequenza a due byte C0 80(in esadecimale) invece della codifica standard a byte singolo 00. La seconda differenza è che i caratteri supplementari (quelli al di fuori del BMP a U+10000 e oltre) sono codificati utilizzando una costruzione a coppia surrogata simile a UTF-16 anziché essere codificati direttamente utilizzando UTF-8. In questo caso ciascuno dei due surrogati è codificato separatamente in UTF-8. Ad esempio, U+1D11E è codificato come sequenza a 6 byte ED A0 B4 ED B4 9E, anziché come codifica UTF-8 a 4 byte corretta di F0 9D 84 9E.

Guarda anche

Riferimenti

Ulteriori letture

  • Tim Lindholm , Frank Yellin (1999). La specifica Java Virtual Machine (seconda ed.). Prentice Hall. ISBN 0-201-43294-3. Estratto il 13-10-2008 .Il documento ufficiale di definizione della Java Virtual Machine , che include il formato del file di classe. Sia la prima che la seconda edizione del libro sono disponibili gratuitamente online per la visualizzazione e/o il download .