Explore Funções de Refatoração no Eclipse JDT

Este artigo descreve as várias refatorações disponíveis em Java™ Development Tools (JDT) do Eclipse, incluindo o que cada refatoração faz, quando usá-la e como usá-la. Ele também explora a funcionalidade dos script de retaforação no Eclipse que permite aos desenvolvedores de biblioteca compartilhar refatorações de seus códigos com seus clientes.

Prashant Deva, Founder, Chronon Systems

Prashant DevaPrashant Deva é o fundador de Placid Systems e o autor do plug-in ANTLR Studio para o Eclipse. Também fornece consultoria relacionada a ANTLR e ao desenvolvimento de plug-in do Eclipse. Escreveu diversos artigos relacionados a ANTLR e a plug-ins do Eclipse e, frequentemente, contribui com ideias e relatórios de erros para as equipes de desenvolvimento do Eclipse. Atualmente está ocupado criando a próxima grande ferramenta de desenvolvedor.


nível de autor Contribuidor do
        developerWorks

07/Dez/2009

As funcionalidades de refatoração no Eclipse fazem dele um Java integrated development environment (IDE) moderno em vez de um editor de texto comum. Usando a refatoração, é facilmente possível fazer alterações no seu código sem se preocupar com quebras em qualquer outro lugar. Com a refatoração, é possível escrever algum código apenas para ver se ele funciona sem se preocupar com sua aparência e depois, de forma rápida e fácil, usar as ferramentas de refatoração para transformar esse código em código limpo e altamente modularizado. Este artigo descreve e mostra como usar algumas das poderosas funções de retaforação disponíveis no Eclipse.

Tipos de refatoração

Rename

Rename provavelmente é a refatoração mais usada em Eclipse. Ela permite renomear variáveis, classes, métodos, pacotes, pastas e quase todos os identificadores Java. Ao renomear um identificador, todas as referências a esse identificador também são renomeadas. O atalho para invocar a refatoração Rename é Alt+Shift+R. Ao invocar o atalho em um identificador no editor Eclipse, uma pequena caixa mostra, dentro do próprio editor, onde é possível alterar o nome do identificador. Ao pressionar Enter, todas as referências a esse identificador também são alteradas.

Move

É possível usar Move para mover uma classe de um pacote para outro. Ela move fisicamente a classe para a pasta que corresponde ao pacote e também altera todas as referências à classe para se referir ao novo pacote.

É possível arrastar e soltar uma classe para um novo pacote na visualização Package Explorer, e a refatoração ocorrerá automaticamente.

Extract Local Variable

A refatoração Extract Local Variable permite designar o resultado de uma expressão Java para uma nova variável local. Use-a para simplificar uma expressão Java complexa por meio de sua rápida divisão em múltiplas linhas. Ou, ao editar o código, digite a expressão primeiro e use esta refatoração para criar automaticamente uma nova variável local à qual designar o resultado. Isso é útil quando o valor de retorno tem um tipo complexo porque o tipo da variável é gerado automaticamente.

É possível invocar esta refatoração no editor. Depois de digitar a expressão que deseja designar a uma variável, pressione Ctrl+1 e selecione Assign statement to a local variable. Uma nova variável com o tipo apropriado é criada para você.

Extract Constant

A refatoração Extract Constant permite converter qualquer número ou cadeia de caracteres literal do seu código em um campo final estático. Após a refatoração, todos os usos desse número ou cadeia de caracteres literal na classe se referem a esse campo, ao invés de se referirem ao próprio número ou à própria cadeia de caracteres literal. Isto é, é possível modificar o número ou cadeia de caracteresliteral em apenas um lugar (o valor do campo), ao invés de fazer uma busca e troca em todo o seu código.

Para usar, selecione o número ou cadeia de caracteres literal no editor, pressione Ctrl+1 e selecione Extract to Constant.

Convert Local Variable to Field

Como o nome sugere, a refatoração Convert Local Variable to Field toma uma variável local e a converte em um campo particular da classe. Todas as referências à variável local depois disso se referem ao campo.

Para usar, selecione uma variável local, pressione Ctrl+1 e selecione Convert Local Variable to Field.

Convert Anonymous Class to Nested

A refatoração Convert Anonymous Class to Nested toma uma classe anônima e a converte em uma classe aninhada do método que originalmente continha a classe anônima.

Para usar, posicione o cursor dentro da classe anônima e selecione Refactor > Convert Anonymous Class to Nested no menu. Uma caixa de diálogo é exibida, solicitando o nome da nova classe. Também é possível configurar propriedades da classe, como especificar se o acesso a ela é público, protegido, privado ou padrão. Também é possível dizer se a classe é final, estática ou uma combinação de ambas.

Como um exemplo, o código na Lista 1 usa uma classe anônima para criar uma Factory de Encadeamento.

Lista 1. Antes da Refatoração Convert Anonymous Class to Nested
void createPool() {
	threadPool = Executors.newFixedThreadPool(1, new ThreadFactory()
		{

			@Override
			public Thread newThread(Runnable r)
			{
				Thread t = new Thread(r);
				t.setName("Worker thread");
				t.setPriority(Thread.MIN_PRIORITY);
				t.setDaemon(true);
				return t;
			}

		});
}

O código na Lista 1 estaria muito mais claro se a classe anônima fosse posicionada separadamente como uma classe interna. Assim, eu executo a refatoração Convert Anonymous Class to Nested, dando o nome MyThreadFactory à nova classe. Isso resulta no código mostrado na Lista 2, que está muito mais claro.

Lista 2. Após a Refatoração Convert Anonymous Class to Nested
private final class MyThreadFactory implements ThreadFactory
	{
		@Override
		public Thread newThread(Runnable r)
		{
			Thread t = new Thread(r);
			t.setName("Worker thread");
			t.setPriority(Thread.MIN_PRIORITY);
			t.setDaemon(true);
			return t;
		}
	}
void createPool(){
	threadPool = Executors.newFixedThreadPool(1, new MyThreadFactory());
}

Convert Member Type to Top Level

A refatoração Convert Member Type to Top Level toma uma classe aninhada e a converte em uma classe de nível superior com seu próprio arquivo Java.

Para usar esta refatoração, posicione o cursor dentro de uma classe aninhada e selecione Refactor > Convert Member Type to Top Level. Se a classe aninhada for uma classe estática, uma caixa mostrando uma visualização da refatoração é exibida imediatamente. Se ela não for uma classe estática, você precisa primeiro declarar o nome do campo que conterá a referência à classe-pai da classe aninhada antes de obter a caixa de visualização. Também é possível declarar o campo como final nesta caixa.

Extract Interface

A refatoração Extract Interface cria uma interface fora dos métodos definidos em uma classe.

Para usar esta refatoração, selecione Refactor > Extract Interface no menu. Uma caixa de diálogo é exibida, solicitando o nome da nova interface. É possível verificar os métodos na classe que será declarada na interface. A caixa de diálogo também permite converter todas as referências válidas para a classe em referências à interface. Observe que a refatoração somente converte referências válidas para a classe no novo tipo de interface. Isso significa que se você não selecionar um método da classe para fazer parte da interface e o Eclipse detectar que uma referência a uma classe usa esse método, essa referência não será convertida no novo tipo de interface. Lembre-se disso para não cometer o erro de pensar que todas as referências a uma classe foram alteradas para o novo tipo de interface.

Extract Superclass

A refatoração Extract Superclass é similar à refatoração Extract Interface descrita anteriormente. Porém, Extract Superclass extrai uma superclasse em vez de uma interface. Se a classe já usa uma superclasse, a classe mais recentemente gerada terá essa classe como sua superclasse, mantendo a hierarquia de classes.

Para usar essa refatoração, certifique-se de que o seu cursor esteja em uma das declarações ou um dos campos de método da classe e selecione Refactor > Extract Superclass. caixa de diálogo exibida é semelhante à caixa de diálogo Extract Interface e permite que você nomeie a nova superclasse e selecione os métodos e campos que serão colocados na superclasse.

Uma enorme diferente entre extrair uma superclasse e extrair uma interface é que os métodos colocados na superclasse são, na verdade, movidos para lá. Assim, se qualquer um desses métodos contiver referências a quaisquer campos na classe original, você obterá um erro do compilador porque elas são invisíveis à superclasse. A melhor solução neste caso é também mover esses campos referenciados para a superclasse.

Extract Method

A refatoração Extract Method permite selecionar um bloco de código e convertê-lo em um método. O Eclipse automaticamente infere os argumentos do método e tipos de retorno.

Isso é útil quando um método é muito grande e você deseja subdividir seus blocos em diferentes métodos. Isso também é útil se você tiver um pedaço de código que é reutilizado em muitos métodos. Ao selecionar um desses blocos de código e fazer uma refatoração, o Eclipse localiza outras ocorrências desse bloco de código e o substitui por uma chamada para o novo método.

Para usar essa refatoração, selecione um bloco de código no editor e pressione Alt+Shift+M. Uma caixa de diálogo é exibida, solicitando o nome e a visibilidade (pública, privada, protegida ou padrão) do novo método. É possível até alterar os parâmetros e tipos de retorno. O novo método é criado com o bloco de código selecionado nele refatorado para usar adequadamente o argumento e os valores de retorno do novo método. O método a partir do qual a refatoração foi originalmente feita agora contém uma chamada para o novo método.

Por exemplo, digamos que eu deseje mover o bloco de código após a chamada para map.get() na Lista 3 para um método separado.

Lista 3. Antes da Refatoração Extract Method
@Override
	public Object get(Object key)
	{
		TimedKey timedKey = new TimedKey(System.currentTimeMillis(), key);
		Object object = map.get(timedKey);

		if (object != null)
		{
			/**
			 * if this was removed after the 'get' call by the worker thread
			 * put it back in
			 */
			map.put(timedKey, object);
			return object;
		}

		return null;
	}

Para fazer isso, eu seleciono o bloco de código no editor e pressiono Alt+Shift+M. Eu configurei o nome do novo método como putIfNotNull(), e o Eclipse produz o código da Lista 4, automaticamente descobrindo os argumentos e os valores de retorno corretos.

Lista 4. Após a Refatoração Extract Method
@Override
	public Object get(Object key)
	{
		TimedKey timedKey = new TimedKey(System.currentTimeMillis(), key);
		Object object = map.get(timedKey);

		return putIfNotNull(timedKey, object);
	}

	private Object putIfNotNull(TimedKey timedKey, Object object)
	{
		if (object != null)
		{
			/**
			 * if this was removed after the 'get' call by the worker thread
			 * put it back in
			 */
			map.put(timedKey, object);
			return object;
		}

		return null;
	}

Inline

A refatoração Inline pode sequenciar uma referência a uma variável ou um método. Quando usada, ela substitui a referência à variável ou ao método pelo valor designado à variável ou à implementação do método, respectivamente. Isso pode ser útil para limpar o seu código nas seguintes situações:

  • Quando um método for chamado somente uma vez por outro método e fizer mais sentido como um bloco de código.
  • Quando uma expressão parecer mais limpa em uma linha, em vez de dividi-la em várias linhas designando valores para variáveis diferentes.

Para usar esta refatoração, posicione o cursor em uma variável ou um método e pressione Alt+Shift+I. Uma caixa de diálogo é exibida solicitando que você confirme a refatoração. Se você estiver refatorando um método, a caixa de diálogo também oferece a opção de excluir o método completamente após executar a refatoração.

Por exemplo, a segunda linha na Lista 5 apenas designa o valor de uma expressão para a variável timedKey .

Lista 5. Antes da Refatoração Inline
public Object put(Object key, Object value)
	{
		TimedKey timedKey = new TimedKey(System.currentTimeMillis(), key);
		return map.put(timedKey, value);
	}

A Lista 6 mostra o mesmo código após eu ter usado a refatoração Inline. Observe que o que anteriormente eram duas linhas de código agora se ajusta claramente em uma única linha de código.

Lista 6. Após a refatoração Inline
@Override
	public Object put(Object key, Object value)
	{
		return map.put(new TimedKey(System.currentTimeMillis(), key), value);
	}

Change Method Signature

A refatoração Change Method Signature permite alterar a assinatura de um método. Ela modificar todas as chamadas para esse método para usar a nova assinatura.

Para usar essa refatoração, selecione Refactor > Change Method Signature. A caixa de diálogo mostrada na Figura 1 é exibida, permitindo alterar tudo sobre o método, incluindo adicionar ou remover parâmetros, alterar a ordem dos parâmetros, alterar o tipo de valor de retorno, incluindo exceções à declaração do método e até mesmo alterar o nome do método.

Figura 1. A caixa de diálogo Change Method Signature
A caixa de diálogo Change Method Signature

Observe que algumas modificações que você fizer no método, como incluir parâmetro e alterar um tipo de retorno, podem fazer com que o código refatorado contenha erros do compilador porque o Eclipse não sabe o que inserir para esses novos parâmetros.

Infer Generic Type Arguments

A refatoração Infer Generic Type Arguments automaticamente tenta estimar os tipos genéricos apropriados para classes usadas em sua forma não processada. Esta refatoração geralmente é usada para converter código pré-Java 5 em código Java 5 e posterior.

Esta refatoração pode até ser invocada no Package Explorer. Basta dar um clique com o botão direito do mouse em qualquer projeto, pacote ou classe no Package Explorer e selecionar Refactor > Infer Generic Type Arguments.

O código na Lista 7 mostra um ConcurrentHashMap que pode considerar Generic Type Arguments. Porém, o código na Lista 7 não especifica o tipo de parâmetros.

Lista 7. Antes da refatoração Infer Generic Type Arguments
private final ConcurrentHashMap map = new ConcurrentHashMap();

Após usar a refatoração Infer Generic Type Arguments, o Eclipse automaticamente determina os parâmetros de tipo corretos e produz o código mostrado na Lista 8.

Lista 8. Após a refatoração Infer Generic Type Arguments
private final ConcurrentHashMap<TimedKey, Object> map =
     new ConcurrentHashMap<TimedKey, Object>();

Migrate JAR File

A refatoração Migrate JAR File permite atualizar facilmente os arquivos Java Archive (JAR) em um caminho de construção do projeto. A maneira usual de atualizar um arquivo JAR no caminho de construção com uma nova versão é fazer o seguinte:

  1. Acesse as propriedades do projeto e remova o arquivo JAR existente do caminho de construção.
  2. Exclua manualmente o arquivo JAR de sua pasta.
  3. Copie o novo arquivo JAR, renomeando-o para refletir o nome pelo qual ele é referenciado em todos os scripts de construção.
  4. Inclua o novo arquivo JAR no caminho de construção manualmente.

A refatoração Migrate JAR File permite fazer tudo isso em uma etapa. Para invocar a refatoração, selecione Refactor > Migrate Jars. Na caixa de diálogo que é exibida, selecione o local do novo arquivo JAR. Na árvore abaixo, selecione o JAR no projeto que será atualizado para a nova versão. Se você selecionar a caixa de opção Replace Jar file contents but preserve existing filename , o novo arquivo JAR é renomeado para corresponder ao nome do antigo arquivo JAR, não quebrando, dessa forma, nenhum script de construção que se refira ao arquivo JAR por esse nome. Em qualquer caso, ao clicar em Finish, o arquivo JAR anterior é excluído, e o novo arquivo JAR é copiado para seu local e automaticamente incluído ao caminho de construção do projeto, fazendo o seu projeto usar o novo arquivo JAR.

Scripts de refatoração

Scripts de refatoração permitem expor e compartilhar ações de refatoração. Isso é extremamente útil quando você está prestes a distribuir uma nova versão de uma biblioteca que pode causar erros para pessoas que estão usando a versão mais antiga. Ao distribuir um script de refatoração junto com a biblioteca, as pessoas que estão usando a versão mais antiga podem simplesmente aplicar o script em seus projetos para fazer seu código usar a nova versão da biblioteca.

Para criar um script de refatoração, acesse Refactor > Create Script. A janela mostrada na Figura 2 é exibida, mostrando o histórico de todas as refatorações que foram executadas na área de trabalho. Selecione aquelas de que precisa, especifique um local para o script a ser gerado e depois clique em Create para gerar o script.

Figura 2. A janela Create Script
A janela Create Script

Para aplicar um script de refatoração existente na sua área de trabalho, selecione Refactor > Apply Script. Na caixa de diálogo que é exibida, selecione o local do script. Clique em Next para ver as refatorações que este script executará, depois clique em Finish para aplicar as refatorações.

Como um exemplo, suponha que a classe com.A seja renomeada para com.B na versão 2 do seu arquivo JAR. Como as pessoas que estão usando a versão 1 do seu arquivo JAR possuem referências a com.A em seu código, simplesmente fazer o upgrade para a nova versão da biblioteca quebrará seus códigos existentes. Porém, é possível distribuir um script de refatoração com o seu arquivo JAR que automaticamente renomeia as referências à classe com.A para com.B, permitindo que as pessoas façam o upgrade facilmente para a nova versão do seu arquivo JAR.

Conclusão

Com as várias refatorações disponíveis no Eclipse, é fácil transformar um pedaço de código feio em um pedaço artístico e bonito. Os scripts de refatoração permitem atualizar facilmente os seus aplicativos sem se preocupar com os clientes tendo de gastar horas consultando a documentação para descobrir o que quebrou seus códigos. As funcionalidades de refatoração do Eclipse verdadeiramente o coloca à frente de outros editores de texto e IDEs.

Recursos

Aprender

Obter produtos e tecnologias

Discutir

  • Os newsgroups da Plataforma Eclipse devem ser sua primeira parada para discutir questões relacionadas ao Eclipse. (Selecionar isso ativará seu aplicativo de leitor de notícias do Usenet padrão e abrirá eclipse.platform.)
  • Os newsgroups do Eclipse têm muitos recursos para pessoas interessadas em usar e estender o Eclipse.
  • Participe dos blogs do developerWorks e faça parte da comunidade do developerWorks.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=454069
ArticleTitle=Explore Funções de Refatoração no Eclipse JDT
publish-date=12072009