1. Qual é o mecanismo de reflexão?
Simplificando, o mecanismo de reflexão significa que o programa pode obter suas próprias informações durante a execução. Em Java, desde que o nome da classe seja fornecido, todas as informações sobre a classe podem ser obtidas através do mecanismo de reflexão.
2. Onde é utilizado o mecanismo de reflexão?
Às vezes, usamos algum conhecimento, mas não sabemos qual é a terminologia profissional. Quando aprendemos jdbc, usamos uma linha de código, Class.forName("com.mysql.jdbc.Driver.class"). newInstance() ; Mas naquela época, eu só sabia que aquela linha de código gerava uma instância do objeto driver e não sabia seu significado específico. Depois de ouvir a lição sobre mecanismo de reflexão, percebi que isso é reflexão. Hoje em dia, muitos frameworks abertos usam mecanismo de reflexão e Struts são todos implementados usando mecanismo de reflexão.
3. Vantagens e Desvantagens do Mecanismo de Reflexão
Por que usar mecanismo de reflexão? Não basta criar objetos diretamente? Isso envolve os conceitos de dinâmico e estático.
Compilação estática: O tipo é determinado em tempo de compilação e o objeto é vinculado, ou seja, passado.
Compilação dinâmica: determine o tipo e vincule o objeto em tempo de execução. A compilação dinâmica maximiza a flexibilidade do Java, incorpora aplicações polimórficas e reduz o acoplamento entre classes.
Em uma palavra, a vantagem do mecanismo de reflexão é que ele pode criar objetos dinamicamente e compilá-los, o que mostra grande flexibilidade. Principalmente no desenvolvimento de J2EE, sua flexibilidade é muito óbvia. Por exemplo, para um software de grande porte, é impossível projetá-lo perfeitamente de uma só vez. Depois que o programa é compilado e lançado, quando se constata que determinadas funções precisam ser atualizadas, não podemos solicitar ao usuário que desinstale as anteriores. um e depois reinstalá-lo A nova versão, se for esse o caso, este software definitivamente não será usado por muitas pessoas. Se for estático, todo o programa precisa ser recompilado uma vez para realizar a atualização da função. Se usar o mecanismo de reflexão, não precisa ser desinstalado. Ele só precisa ser criado e compilado dinamicamente em tempo de execução para realizar a função.
Sua desvantagem é o impacto no desempenho. Usar reflexão é basicamente uma operação interpretada onde podemos dizer à JVM o que queremos fazer e isso atende aos nossos requisitos. Essas operações são sempre mais lentas do que apenas executar a mesma operação diretamente.
4. Que informações podem ser obtidas utilizando o mecanismo de reflexão?
Resumindo, ele pode obter qualquer informação que exista na classe, mas o pré-requisito é saber o nome da classe, caso contrário não haverá mais informações. Primeiro, o objeto Classe deve ser criado com base no nome completo da classe. aula que chega.
Class c=Class.forName("className"); Obs: className deve ser o nome completo, ou seja, deve incluir o nome do pacote, por exemplo, cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();//Cria uma instância do objeto
OK, depois de ter um objeto, tudo fica fácil de manusear. Você pode obter qualquer informação que desejar.
Como obter o construtor
Construtor getConstructor(Class[] params)//Obtém o construtor público de acordo com os parâmetros especificados
Construtor[] getConstructors() //Obtém todos os construtores públicos
Construtor getDeclaredConstructor(Class[] params)//Obtém construtores públicos e não públicos com base em parâmetros especificados
Construtor[] getDeclaredConstructors() //Obtém todos os construtores públicos
Obter método do método de classe
Método getMethod (String name, Class[] params), obtém o método com base no nome do método e no tipo de parâmetro
Método[] getMethods()//Obtém todos os métodos públicos
Método getDeclaredMethod(String name, Class[] params)//De acordo com o nome do método e tipo de parâmetro, obtenha métodos públicos e não públicos
Método[] getDeclaredMethods()//Obtém todos os métodos públicos e não públicos
Como obter atributos em uma classe
Campo getField(String name)//Obtém a variável pública correspondente de acordo com o nome da variável
Field[] getFields()//Obtém todos os métodos públicos da classe
Campo getDeclaredField(String name)//Obtém variáveis públicas e não públicas com base no nome do método
Field[] getDeclaredFields()//Obtém todos os métodos públicos e não públicos da classe
Estes são os mais usados. Se você os conhece, todo o resto será fácil de manusear...
5. O que pode ser feito com o mecanismo de reflexão?
Quando comecei a usar o jdbc, tive vontade de vomitar ao escrever para acessar o banco de dados. Havia oito tabelas, e cada tabela tinha operações de adição, exclusão, modificação e pesquisa. mecanismo de reflexão, então escrevi sobre diferentes classes DAO diferentes na tabela, o que não apenas acelera o desenvolvimento, mas também torna o código redundante. O mais terrível é que eles parecem quase iguais e depois os copiam e modificam diretamente. como é fácil cometer vários erros de baixo nível (maiúsculas e minúsculas, falta mais uma ou uma letra...), um erro pode levar muito tempo para ser encontrado.
Com o mecanismo de reflexão Java, tudo é fácil de manusear. Você só precisa escrever uma classe dao com quatro métodos, adicionar, excluir, modificar e consultar e passar objetos diferentes. classe dao para cada tabela. O mecanismo de reflexão fará o resto automaticamente para nós, esse é o seu benefício. Para ser franco, o mecanismo de reflexão é projetado para nos ajudar a fazer coisas repetitivas e regulares, então muitos softwares que geram código automaticamente agora usam o mecanismo de reflexão para completá-lo, desde que você insira os parâmetros relevantes de acordo com as regras, baixo. programadores de nível são lentos Os lentos foram destruídos, por quê? Como não há necessidade de escrever código, qualquer pessoa pode desenvolvê-lo, então por que os programadores fazem isso? Portanto, só temos uma saída: trabalhar duro e trabalhar mais duro, tornar-se um programador sênior, especializar-se no desenvolvimento de software estúpido e deixar outros programadores se afastarem e se acalmarem, haha ~
6. Exemplo de uso de mecanismo de reflexão para adicionar e verificar dados do banco de dados
Princípio básico: ao salvar dados, retire todos os valores de atributos dos objetos que precisam ser salvos e, em seguida, reúna a instrução SQL para consulta e empacote todos os dados consultados em um objeto java.
Regras do jogo: Como diz o ditado, não há nada sem regras. Especialmente para programas, só se pode fazer coisas com regras. Ok, vamos definir as regras primeiro.
1) Cada objeto de tabela no banco de dados possui uma classe pojo, e cada campo da tabela corresponde a um atributo na classe pojo. Além disso, o nome da classe pojo é igual ao nome da tabela, e o nome do atributo e o nome do campo são iguais. O caso não importa, porque o banco de dados geralmente não diferencia maiúsculas de minúsculas.
2) Adicione o conjunto padrão e obtenha métodos para cada atributo na classe pojo.
Com as regras do jogo, vamos começar a jogar.
1. Primeiro, há uma tabela no banco de dados. Suponha que o nome do banco de dados seja: blogsystem e o nome de uma tabela nele seja userinfo. Como mostrado na imagem:
2. Crie a classe pojo correspondente:
Copie o código do código da seguinte forma:
pacote cn.netjava.pojo;
classe pública UserInfo {
id interno privado;
nome da string privada;
string privada pwd;
idade interna privada;
@Substituir
string pública paraString() {
return "UserInfo [id=" + id + ", nome=" + nome + ", pwd=" + pwd + ", idade="
+ idade + "]";
}
public int getID() {
identificação de retorno;
}
public void setId(int id) {
isto.id = id;
}
public String getNome() {
nome de retorno;
}
public void setNome(Nome da string) {
este.nome = nome;
}
string pública getPwd() {
retornar senha;
}
public void setPwd(String senha) {
isto.pwd = pwd;
}
public int getIdade() {
idade de retorno;
}
public void setAge(int idade) {
esta.idade = idade;
}
}
2. Escreva uma classe de fábrica para obter a conexão com o banco de dados:
Copie o código do código da seguinte forma:
pacote cn.netjava.factory;
importar java.sql.Connection;
importar java.sql.DriverManager;
classe pública Connect2DBFactory {
Conexão estática pública getDBConnection() {
Conexão conexão = null;
tentar {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/blogsystem";
String usuário = "root";
String senha = "netjava";
conn = DriverManager.getConnection(url, usuário, senha);
} catch (Exceção e) {
e.printStackTrace();
}
conexão de retorno;
}
}
3. A diversão começa, escrevendo a classe dao que opera o banco de dados
Copie o código do código da seguinte forma:
pacote cn.netjava.session;
importar java.lang.reflect.Field;
importar java.lang.reflect.Method;
importar java.sql.Connection;
importar java.sql.PreparedStatement;
importar java.sql.ResultSet;
importar java.sql.SQLException;
importar java.sql.Statement;
importar java.util.ArrayList;
importar java.util.List;
importar cn.netjava.factory.Connect2DBFactory;
importar cn.netjava.pojo.UserInfo;
classe pública NetJavaSession {
/**
* Analise a instrução sql que salva o objeto
*
* @param objeto
*: Objeto que precisa ser salvo
* @return: instrução sql para salvar o objeto
*/
public static String getSaveObjectSql (objeto objeto) {
//Define uma string SQL
String sql = "inserir em";
// Obtém a classe do objeto
Classe c = object.getClass();
// Obtém todos os métodos do objeto
Método[] métodos = c.getMethods();
// Obtém todas as propriedades do objeto
Campo[] campos = c.getFields();
// Obtém o nome da classe do objeto
String cNome = c.getNome();
// analisa o nome da tabela a partir do nome da classe
String nomedatabela = cName.substring(cName.lastIndexOf(".") + 1,
cNome.comprimento());
sql += nometabela + "(";
List<String> mList = new ArrayList<String>();
Lista vList = new ArrayList();
for (método método: métodos) {
String mNome = método.getNome();
if (mNome.startsWith("get") && !mNome.startsWith("getClass")) {
String nomeDoCampo = mNome.substring(3, mNome.comprimento());
mList.add(campoNome);
System.out.println("Nome do campo----->" + fieldName);
tentar {
Valor do objeto = método.invoke(objeto, null);
System.out.println("O valor retornado pelo método de execução: " + valor);
if (valor instância de String) {
vList.add("/"" + valor + "/"");
System.out.println("Valor do campo------>" + valor);
} outro {
vList.add(valor);
}
} catch (Exceção e) {
e.printStackTrace();
}
}
}
for (int i = 0; i < mList.size(); i++) {
if (i <mlista.tamanho() - 1) {
sql += mList.get(i) + ",";
} outro {
sql += mList.get(i) + ") valores(";
}
}
for (int i = 0; i < vList.size(); i++) {
if (i <vList.size() - 1) {
sql += vList.get(i) + ",";
} outro {
sql += vList.get(i) + ")";
}
}
retornarsql;
}
lista estática pública getDatasFromDB (String nomedatabela, int Id) {
retornar nulo;
}
/**
* Salve o objeto no banco de dados
*
* @param objeto
*: Objeto que precisa ser salvo
* @return: Resultado da execução do método 1: indica sucesso, 0: indica falha;
*/
public int saveObject(objeto objeto) {
Conexão con = Connect2DBFactory.getDBConnection();
Stringsql = getSaveObjectSql(objeto);
tentar {
// Instrução instrução=(Instrução) con.createStatement();
PreparedStatement psmt = con.prepareStatement(sql);
psmt.executeUpdate();
retornar 1;
} catch (SQLException e) {
e.printStackTrace();
retornar 0;
}
}
/**
* Obtenha o objeto do banco de dados
*
* @param arg0
*: A classe à qual o objeto pertence
*@param id
*: id do objeto
* @return: o objeto a ser encontrado
*/
objeto público getObject (String className, int Id) {
//Obtém o nome da tabela
String nomedatabela = className.substring(className.lastIndexOf(".") + 1,
className.length());
//Cria objeto de classe com base no nome da classe
Classe c = nulo;
tentar {
c = Class.forName(className);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
// Reúna a instrução sql da consulta
String sql = "select * from" + tableName + "onde Id=" + Id;
System.out.println("Encontrar instrução sql: " + sql);
// Obtém link do banco de dados
Conexão con = Connect2DBFactory.getDBConnection();
//Cria uma instância da classe
Objeto obj = nulo;
tentar {
Instrução stm = con.createStatement();
// Obtém o conjunto de resultados retornado executando a instrução de pesquisa
Conjunto de resultados = stm.executeQuery(sql);
// Obtém o array de métodos do objeto
Método[] métodos = c.getMethods();
//Percorre o conjunto de resultados
enquanto (set.next()) {
obj = c.newInstance();
//Métodos para percorrer objetos
for (método método: métodos) {
String nomeMetodo = método.getNome();
//Se o método do objeto começar com set
if (nomedométodo.startsWith("set")) {
// Obtém o nome do campo na tabela de dados com base no nome do método
String nomedacoluna = nomedométodo.substring(3,
nomedométodo.comprimento());
// Obtém o tipo de parâmetro do método
Class[] parmts = método.getParameterTypes();
if (parmts[0] == String.class) {
// Se o parâmetro for do tipo String, obtenha o valor correspondente do conjunto de resultados de acordo com o nome da coluna e execute o método set
método.invoke(obj, set.getString(columnName));
}
if (parmts[0] == int.class) {
método.invoke(obj, set.getInt(columnName));
}
}
}
}
} catch (Exceção e) {
e.printStackTrace();
}
retornar objeto;
}
}
4. Que tal o efeito de iniciar o teste:
Copie o código do código da seguinte forma:
pacote cn.netjava.tester;
importar cn.netjava.pojo.UserInfo;
importar cn.netjava.session.NetJavaSession;
Testador de classe pública {
public static void main(String args[]) {
//Obtém o objeto NetJavaSession
Sessão NetJavaSession = new NetJavaSession();
//Cria um objeto UserInfo
UserInfo usuário = new UserInfo();
//Define as propriedades do objeto
usuário.setId(6988);
usuário.setAge(44);
user.setPwd("senha");
user.setName("campeão");
//Salva o objeto no banco de dados
String sql = session.getSaveObjectSql(usuário);
System.out.println("Instrução SQL para salvar o objeto: " + sql);
//Encontrar objeto
UserInfo userInfo = (UserInfo) session.getObject(
"cn.netjava.pojo.UserInfo", 6988);
System.out.println("Informações obtidas: " + userInfo);
}
}
5. Resultados impressos:
7. Vamos resumir
Em geral, o mecanismo de reflexão Java é muito útil. Ele pode resolver muitas coisas mortas porque o mecanismo de reflexão é muito flexível. Com ele, não precisamos gastar muito tempo escrevendo operações em vez de usar o código do banco de dados. o método gasta mais tempo nas funções lógicas do projeto. Isso pode reduzir bastante o tempo de desenvolvimento e tornar o código mais legível. Muitas estruturas de código aberto existentes usam mecanismos de reflexão. Eles só precisam configurar arquivos e depois chamar seus métodos de acordo com as regras.