Java class file

SectionsEdit

Existem 10 seções básicas para a estrutura do arquivo de classe Java:

  • Magic Number: 0xCAFEBABE
  • Version of Class File Format: as versões menor e maior do arquivo de classe
  • Constant Pool: Pool de constantes para a classe
  • Bandeiras de Acesso: por exemplo, se a classe é abstrata, estática, etc.
  • Esta Classe: O nome da classe atual
  • Super Classe: O nome da super classe
  • Interfaces: Quaisquer interfaces na classe
  • Campos: Quaisquer campos da classe
  • Métodos: Quaisquer métodos na classe
  • Atributos: Quaisquer atributos da classe (por exemplo, o nome do arquivo fonte, etc.)

Magic NumberEdit

Class files são identificados pelo seguinte cabeçalho de 4 bytes (em hexadecimal): CA FE BA BE (as 4 primeiras entradas na tabela abaixo). A história deste número mágico foi explicada por James Gosling referindo-se a um restaurante em Palo Alto:

“Costumávamos ir almoçar a um lugar chamado St Michael’s Alley. De acordo com a lenda local, no passado profundamente escuro, os Grateful Dead costumavam actuar lá antes de o tornarem grande. Era um lugar bem divertido que era definitivamente um Grateful Dead Kinda Place. Quando Jerry morreu, eles até colocaram um pequeno santuário budista. Quando íamos lá, referíamo-nos ao lugar como Cafe Dead. Em algum lugar ao longo da linha, notou-se que este era um número HEX. Eu estava reformulando algum código de formato de arquivo e precisava de um par de números mágicos: um para o arquivo objeto persistente e outro para as classes. Eu usei CAFEDEAD para o formato de arquivo objeto, e no grepping para palavras hexadecimais de 4 caracteres que cabiam depois de “CAFE” (parecia ser um bom tema) eu cliquei em BABE e decidi usá-lo. Naquela época, não parecia ser muito importante ou destinado a ir a lugar algum, a não ser a lata de lixo da história. Então CAFEBABE tornou-se o formato de arquivo de classe, e CAFEDEAD era o formato de objeto persistente. Mas o recurso de objeto persistente foi embora, e junto com ele foi o uso do CAFEDEAD – ele foi eventualmente substituído pelo RMI.

Layout geralEdit

Porque o arquivo de classe contém itens de tamanho variável e não contém também offsets de arquivo embutido (ou ponteiros), ele é tipicamente parsed sequencialmente, do primeiro byte para o final. No nível mais baixo o formato do arquivo é descrito em termos de alguns tipos de dados fundamentais:

  • u1: um inteiro não assinado de 8 bits
  • u2: um inteiro não assinado de 16 bits em ordem de byte big-endian
  • u4: um inteiro não assinado de 32 bits em ordem de byte big-endian
  • tabela: um array de itens de comprimento variável de algum tipo. O número de itens na tabela é identificado por um número de contagem anterior (a contagem é um u2), mas o tamanho em bytes da tabela só pode ser determinado examinando cada um de seus itens.

Alguns desses tipos fundamentais são então reinterpretados como valores de nível superior (como strings ou números de ponto flutuante), dependendo do contexto.

byte offset tamanho tipo ou valor descrição
0 4 bytes u1 =
0xCA hex
número mágico (CAFEBABE) usado para identificar arquivo como estando em conformidade com o formato de arquivo de classe
1 u1 =
0xFE hex
2 u1 =
0xBA hex
3 u1 =
0xBE hex
4 2 bytes u2 minor número da versão do formato de arquivo de classe sendo usado
5
6 2 bytes u2 maior número de versão do formato de arquivo de classe sendo usado.
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).
Para detalhes dos números das versões anteriores ver nota de rodapé 1 em The JavaTM Virtual Machine Specification 2nd edition
7
8 2 bytes u2 contagem de pool constante, número de entradas na seguinte tabela de pool constante. Esta contagem é pelo menos uma maior que o número real de entradas; veja a seguinte discussão.
9
10 cpsize (variável) tabela tabela de pool constante, um conjunto de entradas de pool constante de tamanho variável, contendo itens como números literais, strings e referências a classes ou métodos. Indexada a partir de 1, contendo (contagem constante do pool – 1) número de entradas no total (ver nota).
10+tamanho 2 bytes u2 bandeira de acesso, a bitmask
11+cpsize
12+cpsize 2 bytes u2 identifica esta classe, indexar na piscina constante a uma entrada do tipo “Classe”
13+cpsize
14+cpsize 2 bytes u2 identifica a super classe, indexar na piscina constante a uma entrada do tipo “Classe”
15+tamanho
16+tamanho 2 bytes u2 contagem de interfaces, número de entradas na seguinte tabela de interface
17+tamanho
18+tamanho isize (variável) tabela tabela de interface: uma matriz de índices de comprimento variável de pool constante descrevendo as interfaces implementadas por esta classe
…..
18+tamanho+tamanho 2 bytes u2 contagem de campos, número de entradas na seguinte tabela de campos
19+cpsize+isize
20+cpsize+isize fsize (variável) table field table, array de campos de comprimento variável

cada elemento é uma estrutura field_info definida em https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5

…..
20+tamanho+tamanho+tamanho+tamanho 2 bytes u2 contagem do método, número de entradas na seguinte tabela de métodos
21+cpsize+isize+fsize
22+cpsize+isize+fsize msize (variável) tabela tabela de métodos, array de métodos de comprimento variável

cada elemento é um method_info structure definido em https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6

…<..>
22+tamanho+tamanho+tamanho+tamanho+msize 2 bytes u2 contagem de atributos, número de entradas na seguinte tabela de atributos
23+cpsize+isize+isize+fsize+msize
24+cpsize+isize+isize+fsize+msize asize (variável) table attribute table, array de atributos de comprimento variável

cada elemento é uma estrutura de atributos_info definida em https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7

Representação em uma linguagem de programação tipo CEditar

Desde que C não suporta múltiplas matrizes de comprimento de variáveis dentro de uma estrutura, o código abaixo não irá compilar e serve apenas como uma demonstração.

struct Class_File_Format { u4 magic_number; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces; u2 fields_count; field_info fields; u2 methods_count; method_info methods; u2 attributes_count; attribute_info attributes;}

A constante poolEdit

A tabela constante pool é onde a maioria dos valores literais das constantes são armazenados. Isto inclui valores como números de todos os tipos, strings, nomes identificadores, referências a classes e métodos, e descritores de tipo. Todos os índices, ou referências, a constantes específicas na tabela de pool de constantes são dados por números de 16 bits (tipo u2), onde o valor do índice 1 se refere à primeira constante da tabela (o valor do índice 0 é inválido).

De acordo com as escolhas históricas feitas durante o desenvolvimento do formato de arquivo, o número de constantes na tabela de pool de constantes não é na verdade o mesmo que a contagem do pool de constantes que precede a tabela. Primeiro, a tabela é indexada começando em 1 (ao invés de 0), mas a contagem deve na verdade ser interpretada como o índice máximo mais um. Além disso, dois tipos de constantes (longas e duplas) ocupam dois espaços consecutivos na tabela, embora o segundo seja um índice fantasma que nunca é usado diretamente.

O tipo de cada item (constante) no pool constante é identificado por uma tag de byte inicial. O número de bytes que seguem esta tag e sua interpretação dependem do valor da tag. Os tipos de constantes válidas e seus valores de tag são:

Borbyte de tag Borbytes adicionais Descrição da constante Versão introduzida
1 2+x bytes
(variável)
UTF-8 (Unicode) string: uma cadeia de caracteres prefixada por um número de 16 bits (tipo u2) indicando o número de bytes na cadeia codificada que se segue imediatamente (que pode ser diferente do número de caracteres). Note que a codificação utilizada não é realmente UTF-8, mas envolve uma pequena modificação do formulário de codificação padrão Unicode. 1.0.2
3 4 bytes Integer: um número de complemento de 32 bits em formato big-endian 1.0.2
4 4 bytes Float: um número de ponto flutuante IEEE 754 de 32 bits de precisão única 1.0.2
5 8 bytes Long: um número de complemento assinado de 64 bits de dois no formato big-endian (leva duas ranhuras na tabela constante do pool) 1.0.2
6 8 bytes Duplo: um número de ponto flutuante IEEE 754 de 64 bits de dupla precisão (leva duas ranhuras na tabela de pool constante) 1.0.2
7 2 bytes Referência de classe: um índice dentro do pool constante para uma string UTF-8 contendo o nome da classe totalmente qualificado (em formato interno) (big-endian) 1.0.2
8 2 bytes Referência de corda: um índice dentro do pool constante para uma string UTF-8 (big-endian também) 1.0.2
9 4 bytes Referência de campo: dois índices dentro do pool de constantes, o primeiro apontando para uma referência de Classe, o segundo para um descritor de Nome e Tipo. (big-endian) 1.0.2
10 4 bytes Referência de Método: dois índices dentro do pool constante, o primeiro apontando para uma referência de Classe, o segundo para um descritor de Nome e Tipo. (big-endian) 1.0.2
11 4 bytes Referência do método de interface: dois índices dentro do pool de constantes, o primeiro apontando para uma referência de Classe, o segundo para um descritor de Nome e Tipo. (big-endian) 1.0.2
12 4 bytes Nome e descritor de tipo: dois índices para cadeias de caracteres UTF-8 dentro do pool de constantes, o primeiro representando um nome (identificador) e o segundo um descritor de tipo especialmente codificado. 1.0.2
15 3 bytes Manipulação do método: esta estrutura é usada para representar uma manipulação de método e consiste em um byte de descritor de tipo, seguido por um índice dentro do pool de constantes. 7
16 2 bytes Tipo de método: esta estrutura é usada para representar um tipo de método, e consiste em um índice dentro do pool de constantes. 7
17 4 bytes Dinâmica: esta é usada para especificar uma constante dinamicamente calculada produzida por invocação de um método bootstrap. 11
18 4 bytes InvokeDynamic: é usado por uma instrução invokedynamic para especificar um método bootstrap, o nome da invocação dinâmica, o argumento e os tipos de retorno da chamada, e opcionalmente, uma sequência de constantes adicionais chamadas de argumentos estáticos para o método bootstrap. 7
19 2 bytes Módulo: este é usado para identificar um módulo. 9
20 2 bytes Package: é usado para identificar uma embalagem exportada ou aberta por um módulo. 9

Existem apenas dois tipos de constantes integrais, inteiro e longo. Outros tipos integrais que aparecem na linguagem de alto nível, tais como boolean, byte e short devem ser representados como uma constante inteira.

Nomes de classes em Java, quando totalmente qualificados, são tradicionalmente separados por pontos, tais como “java.lang.Object”. Contudo dentro das constantes de referência de classe de baixo nível, aparece uma forma interna que utiliza slashes, como “java/lang/Object”.

As strings Unicode, apesar do moniker “UTF-8 string”, não são na verdade codificadas de acordo com o padrão Unicode, embora seja semelhante. Existem duas diferenças (ver UTF-8 para uma discussão completa). A primeira é que o ponto de código U+0000 é codificado como a sequência de dois bytes C0 80 (em hexadecimal) em vez da codificação padrão de um byte 00. A segunda diferença é que caracteres suplementares (aqueles fora do BMP em U+10000 e acima) são codificados usando uma construção de par substituto similar ao UTF-16 ao invés de serem diretamente codificados usando UTF-8. Neste caso, cada um dos dois substitutos é codificado separadamente em UTF-8. Por exemplo, U+1D11E é codificado como a sequência de 6 bytes ED A0 B4 ED B4 9E, em vez da codificação correcta de 4 bytes UTF-8 de F0 9D 84 9E.

.

Deixe uma resposta

O seu endereço de email não será publicado.