Perguntas da entrevista da grande fábrica com base no mecanismo de reflexão de Java
Conceito de mecanismo de reflexão
Quando o programa está em execução, o mecanismo de reflexão Java pode conhecer todas as propriedades e métodos desta classe para qualquer classe; para qualquer objeto, ele pode chamar qualquer um de seus métodos e propriedades. Este acesso dinâmico às informações e um método para objetos de chamada dinâmica funções chamadas mecanismo java reflexão .
Por que introduzir o conceito de reflexão
Acredite que você vê o conceito acima, não há ondas em sua mente, aquisição dinâmica de informações , método de objeto de chamada dinâmica , ponto de interrogação preto. O código simples a seguir serve como ponto de partida para i e é explicado da perspectiva da máquina virtual java
- Escreva o seguinte código
public class Main{
public static int number = 1;
public static void main(String args[]) {
System.out.println("hello World");
}
}
- Chame o
javac Main.java
comando paraMain.java
compilar oMain.class
arquivo em um arquivo - Depois de executar o
java Main
comando, a máquina virtual java é iniciada, o processo de carregamento de classe é executado , a estrutura de armazenamento estático da classe é armazenada na área de método e um objeto java.lang.Class que representa a classe é gerado na memória, conforme cada classe na área de método Acesso a dados
O processo acima mostra que, durante a fase de compilação, a classe (classe principal) a ser carregada pela máquina virtual Java já está especificada . Se o seu programa estiver em execução, você precisará repentinamente carregar a classe do servidor remoto (carregando durante a operação). Nesse momento, o mecanismo de reflexão entra em ação .
Há um cenário muito clássico: carregar a classe de driver de banco de dados; somente através dos parâmetros em tempo de execução, você pode determinar se deseja carregar com.java.dbtest.myqlConnection
(classe de driver mysql) ou carregarcom.java.dbtest.oracleConnection
Nesse ponto, apenas uma chamada simples Class.forName(com.java.dbtest.myqlConnection)
pode concluir dinamicamente o processo de carregamento da classe.
Use o mecanismo de reflexão para carregar a classe duas vezes
import java.io.IOException;
import java.io.InputStream;
public class Main{
public static void main(String args[]) throws Exception{
//自定义类加载器
ClassLoader myLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException{
try{
String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if(is == null) {
return super.loadClass(name);
}
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
}catch(IOException e) {
throw new ClassNotFoundException(name);
}
}
};
//使用反射机制加载并实例化
Object obj = myLoader.loadClass("Main").newInstance();
System.out.print(obj instanceof Main);
}
}
//结果为false