[MÚSICA] Olá a todos. Meu nome é Eduardo Guerra. Estamos aqui no curso de Desenvolvimento Ágil com Java Avançado e vamos fazer hands on para ver a parte de reflexão. Vamos criar nesse hands on componente que faz a comparação das propriedades de dois objetos da mesma classe. O que vai ser a novidade é que ele vai procurar essas propriedades tempo de execução. Ou seja, vai ser baseado na estrutura da classe. Então, vamos lá. Vamos criar aqui no eclipse o projeto. Vou chamar aqui de comparador. E aqui eu vou criar uma classe também chamada de comparador. Compa-ra-dor Bom, essa classe aqui eu vou colocar nela método estático mesmo, chamado comparar, e essa classe vai retornar uma lista com as diferenças entre as propriedades. Vai ser uma classe que eu vou criar aqui. Comparar. Esse método comparar, ele tem que receber dois objetos da mesma classe. Como é que eu faço isso? Eu posso usar os tipos genéricos, que a gente já viu aqui no curso. Então, eu defino aqui tipo genérico E, no próprio escopo do método e digo que eu vou ter aqui objeto velho E, e objeto novo, que eu vou estar comparando para pegar as diferenças, E também. Então com isso, eu posso passar qualquer objeto, mas tem que ser do mesmo… tem que ser da mesma classe. Então eu vou vir aqui, vou criar essa classe diferença… A classe diferença é uma classe que é para guardar informação onde eu vou ter aqui o nome da propriedade… Propriedade Eu vou ter aqui objeto com o valor Novo e objeto com o valor Velho. E aí então vou criar aqui construtor para eu poder criar aqui essa diferença, e vou criar também método toString para a gente poder ver se ele está achando as diferenças de forma correta. Então eu vou salvar, e vou criar aqui o meu comparador. Então vou começar criando já a lista de diferenças, chamar aqui de difs. Vai retornar ali. E para ele parar de reclamar que eu não estou retornando nada. Então, a primeira coisa que eu tenho que fazer é pegar a referência da classe de desses objetos, para poder começar a trabalhar com ela. Então, eu vou criar aqui uma variável do tipo class, lembrando que class tem tipo genérico, então eu vou usar ali a interrogação. Vou criar aqui, aí eu vou fazer velho ponto getClass. Então, eu vou ver aqui, vou criar for onde eu vou ver todos os métodos dessa classe. Então, procurando por aqueles métodos get, eu vou pegar todos os métodos de class vou dar o get declared, getMétodos né. Então, todos os métodos eu vou procurar aqueles com que começam [INAUDÍVEL], para eu poder recuperar as propriedades. O que é que são os métodos get? Então a primeira coisa, eu tenho que começar com o get, então eu vou pegar o nome do método, m.getName tem que começar com get. Continuando aqui, O método getter ele também, o que eu quero executar, ele não recebe parâmetros. Então eu tenho aqui o getParameterCount. Isso aqui tem que ser igual a zero. E eu tenho que ter algum retorno. Então o retorno, ele não pode ser Void. Então, eu uso o Void ponto class aqui… por mais estranho que pareça, a gente usa principalmente para essa parte do retorno, para comparar com o Void. O que eu vou fazer aqui, agora que já achei o método get, eu vou invocar ele. Então, eu vou ter aqui o valor Velho, eu vou invocar esse método no objeto Velho, eu vou invocar esse método no objeto Novo… [ÁUDIO_EM_BRANCO] e vou ter os valores ali. Aqui, toda a vez que eu chamo alguma coisa com reflexão, existem vários erros que podem acontecer. E são erros que, às vezes Java, se a gente usa o código normal, eles vão ser detectados tempo de execução. Tempo de compilação. E quando a gente usa reflexão, ele só aparece tempo de execução. Por exemplo, se eu passar uma quantidade errada de parâmetros, ou tipo errado de parâmetro, se eu tentar compilar esse código, ele vai dar… ele vai dar erro de compilação, você não consegue nem rodar o programa. No caso aqui, a gente vê que neste invoke, não posso passar nada, posso passar qualquer quantidade de parâmetro de qualquer tipo. Então aqui eu posso ter esses erros. No caso, não está, está fora do escopo aqui do que a gente está querendo mostrar, eu vou simplesmente dar throws aqui, exception, e vou tirar aqui, na verdade tem várias exceções, é ali que pode acontecer, pode ser uma exceção do próprio método, pode ser, sei lá, está tentando invocar método privado. Então aqui, eu vou comparar se o valor Novo é igual ao valor Velho. Caso não seja, eu vou adicionar uma diferença na lista. Então, diferença d é igual a new diferença Então, a propriedade, e poderia fazer o passo do método, o get, mas vou deixar aqui só o nome do método e o valor novo e o valor velho. Então, está faltando aqui o ponto e vírgula. É basicamente isso. Eu verifico, eu invoco por reflexão os métodos e verifico ali se eles são iguais. No caso aqui, eu não estou considerando a possibilidade de o valor ser nulo, no caso de o valor novo fosse nulo daria exception. Num código de verdade, digamos assim, a gente precisaria verificar isso aqui. No nosso exemplo, eu vou deixar assim mesmo, fica aí como exercício de você tratar essa questão do nulo, tá? Eu vou criar aqui uma classe chamada pessoa com os gets e sets para a gente testar aqui para ver se está funcionando direitinho. Então, eu vou criar aqui uma propriedade nome, uma propriedade sobrenome, e uma propriedade idade. Vou criar aqui o meu construtor para eu poder criar isto mais facilmente ali no código. E vou criar aqui os métodos gets e sets getters and setters, certo? Então, getters e setters, selecionar tudo, OK! Então, agora que eu criei a minha classe para usar no exemplo, eu vou criar aqui método principal onde eu vou criar duas instâncias de pessoa e vou pedir para o meu comparador compará-las. Então, pessoa p é igual a new pessoa. Vou chamar aqui de p1 Então, eu vou criar aqui Eduardo Guerra 36 e vou criar aqui uma outra instância que seria uma versão mais nova onde, sei lá estou com ano a mais aqui. Aí, eu vou chamar aqui de p2. Então eu vou ter, vou retornar aqui uma lista de diferença Certo? A partir do meu comparador. Então, é comparar o p1 com o p2 e no caso ali, ele joga a exceção, então tem que jogar aqui também, E aí eu vou usar aqui para poder imprimir for Each. Então, system ponto out. Aí vou usar o método [INCOMPREENSÍVEL] para fazer o print ali. Certo? Então, eu vou rodar aqui e ele tem que apontar a idade como uma diferença. Eu rodo aqui Opa! Não achou? Alguma coisa deve estar errada. Está comparando, vamos ver aqui no comparador ele está, eu estou criando a diferença só estou esquecendo de adicionar ela na lista. Esse é o problema. Acontece. Aqui é ao vivo. Não é realmene ao vivo, mas estou fazendo aqui, real aqui. Vamos lá. Então eu adicionei aqui a diferença, certo? Agora, sim. Agora, eu vou rodar e ele achou ali a idade. Vamos supor que eu mude o meu sobrenome aqui para War, então quando eu rodar ali ele vai encontrar também. O que é interessante, a gente percebe é que o comparador ele não depende nada da classe pessoa, e está invocando os métodos dela. Inclusive se eu vier aqui, com uma nova informação, por exemplo, cargo, vou acrescentar aqui no meu construtor, cargo e tenho que acrescentar os gets e sets também, que o meu comparador, ele depende disso. Então, quando eu salvar aqui o principal, vai dar problema, porque eu vou ter que botar o cargo aqui. Então, vou botar aqui pesquisador. A princípio, ele vai rodar e vai fazer a comparação da mesma forma… e, se eu alterar, por exemplo, vamos supor que eu fui promovido a coordenador de alguma coisa, quando eu rodar, ele vai pegar a diferença aqui baixo. Estão vendo? Então, eu espero que com esse exemplo tenha ficado mais claro como é que a gente consegue fazer as coisas de forma mais flexível utilizando reflexão, e inclusive adaptando a mudanças nas próprias classes. Certo? Então, continue no nosso curso. Até à próxima aula! [MÚSICA]