DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:
 
 

  Este é um post disponível para assinantes MVP
Este post também está disponível para assinantes da Java Magazine DIGITAL ou para quem possui Créditos DevMedia.  Clique aqui para saber mais!


Artigo Java Magazine 14 - A dinâmica de Java

Artigo publicado pela Java Magazine 06.

Esse artigo faz parte da revista Java Magazine edição 14. Clique aqui para ler todos os artigos desta edição

jm14_capa.JPG

A Dinâmica de Java

Reflection e Metaprogramação

Conheça técnicas sofisticadas do uso da metaprogramação em Java – dos fundamentos a proxies dinâmicas e geração de bytecodes

Sabemos que a linguagem Java introduziu, a milhões de programadores, a arquitetura de máquina virtual, um modelo de objetos forte, o garbage collection e a programação concorrente. Mas há outro item importante e menos reconhecido também popularizado pelo Java: a metaprogramação. Neste artigo vamos examinar recursos que, apesar de disponíveis há um bom tempo na plataforma, ainda são pouco explorados por muitos desenvolvedores.

Metaprogramação é uma daquelas coisas que parecem mais complicadas do que são. Muita gente tem receio de mexer com recursos muito dinâmicos, que lembram mais a construção de compiladores do que de aplicações comuns. Mas tudo é questão de prática, até de hábito. Por exemplo, ao construir comandos SQL no código você está criando parte da sua aplicação dinamicamente. Só estamos mais acostumados a fazer isso com SQL do que com Java.

Vamos também mostrar um panorama geral do tópico de metaprogramação. Isso inclui as APIs tradicionais em java.lang.reflection, mas vai além, explorando as possibilidades mais recentes e avançadas do Java, como proxies dinâmicas, além de mostrar coisas que vêm por aí.

Histórico e um pouco de teoria

Programas são dados. Esse axioma da metaprogramação de fato é verdadeiro desde a introdução do conceito de “programa armazenado”. A idéia é atribuída a John Von Neumann (1946), por isso computadores modernos são chamados “máquinas de Von Neumann”, com sua arquitetura abstrata composta por CPU e memória, e o programa armazenado na memória principal da mesma forma que os dados. Essa arquitetura demorou para se tornar predominante, pois o preço da memória era muito alto nos anos 40-50; por isso os programas eram mais freqüentemente lidos instrução por instrução (a partir de cartões perfurados ou fitas magnéticas). Isso acontecia à medida que iam sendo executados, e o computador só mantinha na memória principal uma instrução por vez, ou, no máximo, um cache minúsculo para agilizar loops curtos.

Se os programas são dados e são representados na memória como uma seqüência de bytes, um passo lógico é querer manipulá-los da mesma forma como fazemos com outros dados. Mas um código executável normal (compilado) é muito complexo para ser manipulado corriqueiramente; o hardware antigo não suportaria arquiteturas complexas como nossas JVMs. Interpretar código fonte ou compilá-lo era muito demorado – programadores costumavam iniciar compilações à noite e pegar o resultado somente no dia seguinte, isso para programas de poucos Kb.

A solução exigida era uma linguagem e um runtime planejados para funcionamento dinâmico desde o começo. Essa solução surgiu em 1960 com o Lisp. Além de inovar com as VMs, garbage collection e a programação funcional, o sistema Lisp passou a representar o programa compilado num formato que era um meio-termo entre o código binário da CPU (executável diretamente) e o ASCII do código fonte (mais fácil de manipular). Esse formato intermediário é uma estrutura de dados muito eficiente, que permite um desempenho razoável mesmo por um interpretador. Veja um exemplo na Listagem 1.

O aspecto esquisito do código (para nós) deve-se a essa representação do programa “executável”. A compilação transforma o programa numa “lista de listas” (daí o nome da linguagem, que vem de List Processing – processamento de listas).

A lista-raiz do corpo da função fatorial tem como primeiro elemento o cond (condicional): uma referência para a função que faz o papel do if ou switch. O segundo elemento dessa lista-raiz é uma lista de cláusulas para o cond. Cada cláusula é outra lista, com a estrutura "(condição resultado)". Na primeira cláusula a condição é outra lista, que executa a função "=" com os argumentos (n 0), e o resultado é 1. Na segunda cláusula, que só é executada se as condições anteriores falharem, a condição é o valor t (true), portanto a cláusula sempre executa se o processamento chegar até ela. O resultado é outra lista, com uma expressão mais complexa, envolvendo listas aninhadas.

Você pode imaginar que, com uma representação tão simples do programa executável (listas aninhadas onde cada elemento é uma função, um valor ou outra lista que também pode ser executável) pode ser construída dinamicamente pelo programa de forma muito fácil e eficiente. Não temos espaço para técnicas avançadas em Lisp – nem estamos na Lisp Magazine! –, mas um exemplo modesto já ilustra as possibilidades dessa idéia (veja a Listagem 2).

A “meta-função” ind-f implementa qualquer função recursiva que gera um resultado a partir de computações para uma seqüência 0,1,2,...,N, daí o nome ind-f (do “método indutivo” de prova de teoremas). Observe que um dos parâmetros adicionais dessa meta-função (n0) é um valor comum, mas o outro argumento (op) é outra função. Se você editar o código de ind-f, substituindo todas as ocorrências de n0 por 1 e todas ocorrências de op por "*", o resultado será igual ao fatorial do primeiro exemplo. Por isso nossa nova definição de fatorial funciona. E podemos fazer outras definições, como a função somatoria que implementa um algoritmo diferente.

"



ATENÇÃO! A exibição deste artigo foi interrompida.


  Este é um post disponível para assinantes MVP
Este post também está disponível para assinantes da Java Magazine DIGITAL ou para quem possui Créditos DevMedia.  Clique aqui para saber mais!






    0 COMENTÁRIO

[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.


Nenhum comentário foi postado - seja o primeiro a comentar!



Publicidade
Autor
Osvaldo Pinali Doederlein

é Mestre em Engenharia de Software Orientado a Objetos e Arquiteto de Tecnologia da Visionnaire Informática, trabalhando em projetos de software e prospecção tecnológica.


Space do autor
Estatísticas
Favorito:
Comentários:
Feedback:
Utilidade:
0   0
[Fechar]

Você precisa estar logado para dar um feedback.

Clique aqui para efetuar o login
[Fechar]


Este post está fechado. Saiba mais sobre a assinatura MVP!
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2012 - Todos os Direitos Reservados a web-03