[MÚSICA] Olá a todos, meu nome é Eduardo Guerra e esse é o Curso de Desenvolvimento Ágil com Java Avançado. Hoje eu vou falar sobre reflexão Java, a gente vai aprender a usar a API de reflexão da linguagem Java. Só aproveitando para falar a gente não vai ver a API completa a ideia aqui desse módulo é dar uma pequena noção, uma ideia para vocês sobre o que dá para fazer com reflexão. Deixando claro que a gente não vai se aprofundar muito aí nesse tema. Mas eu acho que o que a gente vai ver dá para cobrir o básico e dá para você ter uma boa noção de como utilizar a reflexão. No material escrito eu vou passar aí uma excelente referência se você quiser se aprofundar mais nisso. Vamos lá. Então, a API de reflexão, ela trabalha ali com os velhos amigos da gente no código. Eu acho que às vezes uma dificuldade de uma API está você entender os conceitos dela. Uma vez eu fui trabalhar com uma API que mexia com 3D e eu vi que a minha dificuldade não era a API si, eram os conceitos de sombra, de câmara, de posição que aquela API utilizava e não a API si. Então, na verdade a grande dificuldade de trabalhar com uma API é você não entender bem os conceitos com os quais ela trabalha. E no caso da API de reflexão, ela trabalha com os nossos velhos conhecidos aí, classes, métodos, atributos e etcetera. E aí o que a gente consegue obter de uma classe ou de método é aquelas informações que a gente sabe que uma classe ou método tem. O que a gente consegue fazer com uma classe ou com método é aquilo que a gente consegue fazer com eles no código mesmo. Então, eu não acho que seja uma API complicada de você entender. Vamos ver! Então a base da API é a classe Class, essa classe representa uma classe. Então, toda a classe, ela vai ter uma instância da classe Class que representa ela, inclusive a própria classe Class tem uma instância dela mesma que representa ela. Dá nó na cabeça mas é isso aí. Bom, como é que a gente obtém a referência de uma classe? Como é que a gente obtém a instância da classe Class? A gente tem basicamente três formas de fazer isso. Uma delas é através da referência estática da classe, ou seja, do nome da classe ponto Class, então você fala, olha eu quero o Class dessa classe aqui. Então, eu quero a representação tempo de execução dessa classe, então, você consegue obter dessa forma. Outra forma é assim. eu tenho objeto, eu não sei de que classe é esse objeto mas eu quero pegar. Então você dá o objeto ponto getClass. Você está pegando a classe de objeto. Às vezes por exemplo, você recebe lá object como parâmetro e aí no momento que você der o getClass você já vai estar pegando qual é que é a classe daquele object. E por fim, o Class forName, talvez vocês lembrem da aula de JDBC que a gente usa o Class forName para carregar o driver do banco de dados. E o Class forName ele pega a instância de Class a partir de uma String com o nome dessa classe. No caso lá da classe do banco de dados, a gente fazia isso para poder carregar essa essa classe memória, que fazia a máquina virtual carregar aquela classe do driver. Aqui, se a gente já tem a classe carregada, ele vai simplesmente retornar a instância de Class daquela String que você está passando. Isso aí é especificamente muito útil se você está por exemplo, pegando uma determinada classe que você quer usar de arquivo ou de banco de dados. Bom, como é que cria objeto? A gente pega a instância de Class e a gente também tem duas formas. Se a gente vai chamar o construtor sem parâmetros, a gente pode chamar o newInstance. E se a gente quer utilizar construtor, aí a gente tem que pegar o construtor da classe, dando o getConstructor e passando quais os tipos de parâmetros que aquele construtor tem e aí a gente chama o newInstance passando os parâmetros que aquele construtor espera receber. Procurando métodos a gente pode usar o getMethods que pega todos os métodos públicos da classe, sejam ele definidos naquela própria classe ou sejam na superclasse. A gente tem o getDeclaredMethods, que ele pega os método, todos os métodos mais declarados uma classe, o que significa que ele vai pegar os métodos default, protegidos e privados. Porém, não vai incluir métodos que são definidos na superclasse, por mais que eles sejam públicos, e a gente também tem como pegar o método pelo nome e seu tipo de parâmetro. Quem trabalha com Java, sabe que método, ele é identificado unicamente pelo seu nome e pelos seus tipos de parâmetros. Você pode ter por exemplo, método com o mesmo nome desde que os tipos de parâmetro que ele receba sejam diferentes. Então a gente consegue trabalhar dessa forma, a gente consegue recuperar método específico a partir do seu nome e os parâmetros que ele recebe. Invocando o método, é bem fácil. A gente chama o método invoke na instância de método e o primeiro parâmetro ele vai ser o objeto no qual a gente está invocando o método. Se for método estático, eu posso passar null ali. Mas via de regras, se é método de uma classe, de instância, eu tenho que passar qual instância eu estou invocando aquele método. Esse é o primeiro parâmetro do invoke. E os outros parâmetros, você pode passar de acordo com os parâmetros que aquele método espera receber. Então se ele espera receber uma String e inteiro, você vai passar uma String e inteiro. Certo? Então o que é que a gente faz com isso tudo? Uma coisa interessante, que é feita bastante aí com a reflexão, é você ler por exemplo, quais as classes que você vai utilizar de aquivo de configuração e a partir dali criar os componentes da sua aplicação. Repare que tem vários frameworks que você usa, que você tem que definir lá certas classes de arquivo. O que é que você está fazendo? Você está definindo essas classes que o framework vai instanciar tempo de execução, ou seja, ele vai descobrir quais são aquelas classes tempo de execução. E a gente também pode buscar, procurar métodos para a gente invocar também tempo de execução. Por exemplo, eu quero todos os métodos começados com get ou todos os métodos começados com set. Quem é dos antigos aí que usou JUnit, sabe que inicialmente os métodos de teste não tinham annotation. Eles começavam com testes. Então no caso o JUnit procurava todos os métodos que tinham esse começo, que começavam dessa forma. Então a gente pode usando reflexão também procurar métodos com certas características, ou por exemplo, eu tenho lá uma tabela do banco de dados, eu vou procurar uma propriedade que seja relativa, tenha o mesmo nome. Então a gente pode fazer tudo isso daí, descobrir e invocar esses métodos tempo de execução, ou seja, adaptar o nosso componente ali às classes com as quais ele está trabalhando. Com isso a gente consegue uma reutilização muito maior. Certo? Então, espero que tenha dado para pegar uma introduçãozinha aí à reflexão e vamos ver aí no hands on também, acho que vai dar para ficar mais claro como é que isso dai pode ser recurso extremamente poderoso. Muito obrigado e continuem na próxima aula! [MÚSICA]