Pergunta

Em Java, é possível criar uma definição de classe na mosca enquanto um aplicativo está em execução e, em seguida, criar um objeto dessa classe?

Por exemplo, um aplicativo em execução leria em um arquivo de texto que contém uma lista de membros de classe para incluir na nova classe. O aplicativo, então, definir uma definição de classe com base na lista de membros e, em seguida, insantiate-lo.

Foi útil?

Solução

Sim, é possível fazê-lo em teoria seu arquivo de classe é o código de byte, que está no final de um array de bytes! então você pode usar o método defineClass (String, byte [], int, int) para obter uma instância de classe que pode ser usada para objetos instanciar via reflexão.

Na prática, você pode usar algo como CGLIB ou javaassist .

Você também pode usar o longo caminho de gerar o código java em um arquivo, invocando o compilador, em seguida, carregar o arquivo.

Outras dicas

Você pode gerar dinamicamente classes usando ASM

Você pode fazer isso por escrito o código para a nova classe para um arquivo, em seguida, chamar o compilador Java nesse arquivo e usando um carregador de classe para carregar dinamicamente essa classe em seu aplicativo em execução. Apache Tomcat faz isso para suas páginas JSP; que leva o código, faz algumas alterações a ele, envolve-o em um bloco try / catch no meio de uma classe, que, em seguida, escreve para o sistema de arquivos, compila-lo, e usa um carregador de classe para obter e processar-lo para atender as solicitações.

Claro que é possível. Veja por exemplo este artigo .

Talvez o simples solução (em termos de não exigir bibliotecas extras) seria usar o Java compilador API que vem com Java 6. Você só apenas ser capaz de gerar o .java, compilação e depois executar uma Class.forName () .

Talvez um pouco exagerado, o Apache BCEL (Code Library Engenharia Byte) pode ser usado para criar arquivos class durante a execução.

Embora eu não tentei me, de modo concebível, pode-se, então, criar uma classe, carregá-lo, e instanciá-lo durante o tempo de execução.

Sim, isso é possível.

Você pode criar classes com Javassist em tempo de execução definindo o corpo da classe e fazer Javassist compilar sua nova classe.

Javassist tem um compilador personalizado que cria bytecode com base na definição de sua classe. Ele tem algumas maneiras específicas para lidar com as coisas, mas é muito fácil e intuitivo de usar esta biblioteca.

Javassist é usado em JBoss, e eu acho que é uma referência boa:)

O mesmo pode ser conseguido com BCEL , no entanto, é muito mais difícil (mas desta forma você ter mais controle sobre o que está sendo gerada).

Você provavelmente poderia fazer algo assim com JRuby ou Groovy JPython ou se for preciso.

Se você estiver sentindo particularmente masoquistas você pode olhar para BCEL .

Se você quiser Java e metaprogramming, uso Groovy .

ASM é a mais baixa biblioteca nível de bytecode para Java, suponho. Isso torna muito difícil, mas também muito poderoso. Eu recomendo a leitura documentação do ASM ( PDF ) para realmente entender como geração de bytecode em Java funciona. Essa documentação também explica como carregar o bytecode no carregador de classe (outro tema difícil de fazer direito).

Depois que você pode usar uma das bibliotecas de nível superior, se torna a sua vida mais fácil, e entender o que eles fazem. Para muitos casos, tais como os proxies gerando, o CGLIB é útil e simples de usar. Para mais poder, muitos mencionados Javassist (I haven' t usou -. CGLIB e ASM têm sido bons para mim)

Houve uma recente pergunta aqui sobre in-memory compilação que deve lhe dar algumas dicas sobre o que fazer depois que você conseguiu gerar o código-fonte.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top