Introdução detalhada ao processo básico de carregamento da classe Java
Processo básico:
- Carregue o fluxo de bytes binários que define a classe com base no nome totalmente qualificado da classe.
- Converta a estrutura de armazenamento estático representado pelo fluxo de bytes na estrutura de dados de tempo de execução da área do método
- Gere um objeto java.lang.class representando essa classe na memória e use -o como um método para acessar vários portais de acesso a dados dessa classe.
A classe Array em si não é criada através do carregador de classe, mas é criada diretamente pela máquina virtual Java, e o tipo de elemento da classe de matriz é carregado pelo carregador de classe.
Tipo de elemento Classe de matriz: o tipo de matriz após a remoção de todas as dimensões.
Verificação do formato de arquivo:
- 0xcafeBaby começa com o número mágico;
- A máquina virtual atual pode lidar com o número da versão primária e secundária;
- tipo constante;
- Tipo de execução do índice;
- Tipo de dados codificado UTF8,
Verificação de metadados: Análise semântica do bytecode Descrição Informações:
- Se existe uma classe pai;
- Se a classe dos pais herda a classe final modificada;
- Se uma classe não extraída implementa os métodos que precisam ser implementados na classe ou interface dos pais;
- Substituir os campos e métodos da classe, sobrecarregar contradições;
Verificação do bytecode: determine a legalidade e a correção do programa por meio de análise semântica de fluxo e fluxo de controle e verificação da análise do corpo do método.
- Verificação de referência do símbolo: Quando a máquina virtual converte referência de símbolo em referência direta, no estágio de análise, ele executa a verificação correspondente em informações fora da própria classe.
- Se a classe correspondente pode ser encontrada por nomes totalmente qualificados descritos por caracteres em referências simbólicas;
- Especifica se existem descritores na classe que correspondem ao campo do método, bem como métodos e campos descritos pelo nome simples;
- Acessibilidade de classes, campos e métodos em referências simbólicas.
Preparação: aloce a memória para variáveis de classe na área do método e defina o valor inicial das variáveis de classe.
- O valor inicial geralmente é o valor zero do tipo de dados e o valor modificado final é diretamente inicializado com o valor correspondente.
- As variáveis de classe são variáveis estaticamente modificadas, distinguidas das variáveis de instância.
Análise: A máquina virtual substitui referências simbólicas no pool constante pelo processo de referência direta
Constant_class_info, constant_fieldref_info, constant_methodref_info ..
- Referência de símbolos: Um conjunto de símbolos descreve o destino referenciado. Qualquer forma de literais pode ser usada para localizar o alvo sem ambiguidade. Não tem nada a ver com a implementação da memória da máquina virtual e independentemente de o destino de referência ser carregado.
- Referência direta: um ponteiro diretamente para o destino, um deslocamento ou um identificador que está indiretamente localizado ao alvo, está relacionado à memória implementada pela máquina virtual. O objeto de destino relacionado a referência direta deve ser carregado.
- . . .
Inicialização: comece a executar o código do programa Java na definição da classe. Execute o método <ninit> () do construtor de classe,
<ninit> ():
- O compilador coleta automaticamente as ações de atribuição das variáveis de classe na classe de acordo com a ordem de definição no arquivo de classe e mescla as instruções do bloco de instrução estática. O bloco de declaração estática pode acessar apenas as variáveis definidas antes.
- Diferente do construtor de classe, o construtor da classe pai não precisa ser chamado como mostrado. A máquina virtual garante que a classe pai <ninit> () tenha sido executada antes da execução da subclasse.
- O bloco de declaração estática na classe pai é executado primeiro.
- <ninit> () não é necessário para classes ou interfaces e não será gerado se não houver operação de atribuição de variável ou bloco de instrução estática.
- O <ninit> () da interface não precisa executar o <ninit> () da interface pai primeiro, e a mesma classe de implementação de interface <ninit> () não é necessária.
- Segurança do thread: a máquina virtual garante que o <ninit> () seja bloqueado corretamente e sincronizado em um ambiente multithread. Apenas um thread pode acessar o <ninit> () da classe de inicialização ao mesmo tempo.
Obrigado pela leitura, espero que isso possa ajudá -lo. Obrigado pelo seu apoio a este site!