Qualquer motivo para limpar as importações não utilizadas em Java, além de reduzir a desordem?

99

Existe algum bom motivo para evitar instruções de importação não utilizadas em Java? Pelo que entendi, eles estão lá para o compilador, portanto, muitas importações não utilizadas não terão nenhum impacto no código compilado. É apenas para reduzir a desordem e evitar conflitos de nomenclatura no futuro?

(Eu pergunto porque o Eclipse dá um aviso sobre importações não utilizadas, o que é meio irritante quando estou desenvolvendo código, porque não quero remover as importações até ter certeza de ter concluído o projeto da classe.)

Kip
fonte

Respostas:

86

Não acho que problemas de desempenho ou algo parecido sejam prováveis ​​se você não remover as importações.

Mas pode haver conflitos de nomenclatura, em casos raros, como importar a interface da lista.

No Eclipse, você sempre pode usar um atalho (depende do sistema operacional - Win: Ctrl + SHIFT + Oe Mac:) COMMAND + SHIFT + Opara organizar as importações. O Eclipse então limpa a seção de importação e remove todas as importações obsoletas, etc. Se você estiver precisando de algo importado novamente, o Eclipse os adicionará automaticamente enquanto você está concluindo a instrução com Ctrl + SPACE. Portanto, não há necessidade de manter o código não utilizado em sua classe.

Como sempre, o código não utilizado irá distrair você e outras pessoas enquanto lê o código e deixar algo em seu código ativo porque talvez eu precise disso mais tarde é considerado uma prática ruim.

Janusz
fonte
22
Na verdade, é Ctrl + Shift + O no Windows.
Matt Ball,
1
Ctrl + Shift + O no Linux também. Provavelmente o mesmo no BSD.
WhyNotHugo
2
Outra maneira de ctrl+3acessar a ação de organizar importações é clicando (pelo menos em windwos) e digitando importações. É obviamente mais lento do que ctrl + shift + O, mas é uma maneira de encontrá-lo rapidamente (e muitas outras ações que você lembra ou está apenas tentando encontrar), mesmo se você não se lembrar do atalho específico para isso.
epeleg,
53

Uma seria que, se você remover a classe referenciada pela importação do caminho de classe, não obterá um erro bobo do compilador que não serve a nenhum propósito. E você não obterá falsos positivos ao realizar uma pesquisa "onde usou".

Outro (mas isso seria de natureza muito específica) seria se a importação não usada tivesse conflitos de nomenclatura com outra importação, fazendo com que você usasse nomes totalmente qualificados desnecessariamente.

Adendo: Hoje o servidor de compilação começou a falhar na compilação (nem mesmo a execução do teste) com um erro de falta de memória. Ele funcionou bem para sempre e os check-ins não tiveram nenhuma alteração no processo de construção ou adições significativas que poderiam explicar isso. Depois de tentar aumentar as configurações de memória (isso é executar uma JVM de 64 bits em um CentOS de 64 bits!) Para algo muito além de onde os clientes poderiam compilar, examinei os check-ins um por um.

Havia uma importação imprópria que um desenvolvedor usou e abandonou (eles usaram a classe, importaram-na automaticamente e então perceberam que era um erro). Essa importação não utilizada puxou uma camada separada inteira do aplicativo que, embora o IDE não esteja configurado para separá-los, o processo de construção está. Essa única importação arrastou tantas classes que o compilador tentou compilar sem ter as bibliotecas dependentes relevantes no caminho de classe, que isso causou tantos problemas que causou o erro de falta de memória. Demorou uma hora para resolver este problema causado por uma importação não utilizada.

Yishai
fonte
4
@Yishai, se você usar o Eclipse, procure Salvar Ações, que podem normalizar o código-fonte sempre que você salva.
Thorbjørn Ravn Andersen,
2
@EJP, embora eles não afetem o bytecode resultante, o compilador precisa resolvê-los para entender o bytecode que precisa criar.
Yishai
3
@EJP, todo o adendo fala sobre o tempo de compilação ("o servidor de compilação começou a falhar na compilação").
Yishai
1
Ainda não entendo como a importação sozinha pode causar tudo isso?
Thorbjørn Ravn Andersen
1
@Yishai, desculpe, mas eu não acredito. Você diagnosticou isso incorretamente. A importação não deve ter tal efeito, a menos que a classe tenha sido realmente usada. Tudo o que a instrução import faz é dizer ao compilador em qual pacote essa classe está. O compilador apenas tenta compilar implicitamente quando precisa de informações de tipo sobre essa classe.
Marquês de Lorne
9

Do ponto de vista purista, qualquer dependência é uma "restrição" ao produto e pode, portanto, causar problemas de manutenção posteriormente.

Por exemplo, vamos supor que seu programa use a classe com.XYZObjectPool e que mais tarde você decida não usá-la, mas nunca removerá a importação. Se alguém agora deseja instanciar org.WVYObjectPool e apenas referir-se a ObjectPool, eles não recebem nenhum aviso sobre isso até que em algum lugar abaixo haja um problema de elenco ou problema de invocação.

A propósito, este não é um cenário irreal. Cada vez que você fazia o Eclipse perguntar qual versão específica do X você queria importar, e você escolheu uma entre muitos pacotes, é um cenário em que se você fez a importação lá, você pode ter feito a escolha errada sem saber sobre ela.

De qualquer forma, você pode pedir ao Eclipse para limpar isso para você

Uri
fonte
3

Aviso? Peça ao Eclipse para limpá-los automaticamente para você. É isso que o IntelliJ faz. Se for inteligente o suficiente para avisá-lo, deve ser inteligente o suficiente para limpá-los. Eu recomendo procurar uma configuração do Eclipse para dizer a ele para parar de ser tão importuno e fazer algo.

duffymo
fonte
4
Isso é salvar ações. Pessoalmente, gosto que o Eclipse só mude seu código quando você o solicitar explicitamente.
Thorbjørn Ravn Andersen,
1
@ Thorbjørn: Concordo, especialmente se for uma classe que parei de usar por um tempo, mas que espero estar adicionando novamente em breve.
Donal Fellows
2
@Donal, bem, é para isso que serve o Ctrl-Space.
Thorbjørn Ravn Andersen,
3

Isso tem a ver com a clareza do programa útil para manutenção.

Se você tivesse que manter um programa, descobrirá como é útil ter uma única importação de classe por linha.

Pense no seguinte cenário:

import company.billing.*;
import company.humanrerources.*;

// other imports 


class SomeClass {
      // hundreds or thousands of lines here... 
    public void veryImportantMethod() {
      Customer customer;
      Employee comployee;
      Department dept. 
      // do something with them
     }
 }

Quando você está corrigindo bugs ou mantendo parte do código (ou apenas lendo), é muito útil para o leitor saber a qual pacote as classes usadas pertencem. Usar a importação de curinga como mostrado acima não ajuda para esse propósito.

Mesmo com um IDE, você não quer passar o mouse ou pular para a declaração e o retorno, é mais fácil se você entender em termos de funcionalidade de quais outros pacotes e classes o código atual depende.

Se for um projeto pessoal ou algo pequeno, realmente não importa, mas para algo maior que deve ser usado por outros desenvolvedores (e mantido ao longo dos anos), isso é OBRIGATÓRIO.

Não há absolutamente nenhuma diferença de desempenho com nenhum.

OscarRyz
fonte
3

Para sua informação, isso me pegou de surpresa, pois não achei que organizar importações realmente removesse importações não utilizadas, pensei que apenas as separava.

Remover automaticamente as importações durante uma operação de salvamento me causou alguns problemas quando, por exemplo, durante o desenvolvimento ou teste você tem um problema e comenta algum código, quando você o salva, as importações usadas pela seção comentada do código são removidas. Às vezes, isso não é um problema, pois você pode desfazer ( Ctrl+ Z) as alterações, mas outras vezes não é tão simples, pois você pode ter feito outras alterações. Eu também tive um problema onde quando eu descomentei o código (eu já comentei e salvei, removendo assim as importações para aquele código), ele automaticamente tentava adivinhar as importações que eram necessárias e pegava as erradas (por exemplo, acho que tinha uma StringUtilsclasse sendo usada e escolheu outra com o mesmo nome da biblioteca errada).

Prefiro organizar manualmente as importações em vez de salvá-las.

John
fonte
2

Para o eclipse, eu uso isso: janela -> preferências -> java -> editor -> salvar ação -> marque a caixa de seleção para organizar importações (há muitas outras coisas úteis lá também, como formatação, tornar os campos finais e assim por diante. .). Então, quando eu salvo meu arquivo, o Eclipse remove as importações de unessacry. Na minha opinião, se você não precisa de algo, remova-o (ou deixe que seja removido por eclipse).

kukudas
fonte
2

Você pode comentar as instruções de importação não utilizadas e os avisos não vão incomodá-lo, mas você pode ver o que tinha.

Sharon
fonte
2
@DimaSan Na verdade, sim: a pergunta diz que não quero remover as importações até ter certeza de ter concluído o projeto da classe.
The Vee
1

Não há nenhum impacto no desempenho, embora para facilitar a leitura você possa torná-lo limpo. Remover importações não utilizadas é bastante simples tanto no Eclipse quanto no IntelliJ IDEA.

Eclipse

Windows / Linux -    Ctrl+ Shift+O

Mac -                        Cmd+ Shift+O

IntelliJ IDEA ou Android Studio

Windows / Linux -    Ctrl+ Alt+O

Mac -                        Cmd+ Alt+O

Madan Sapkota
fonte
0

Eu li em algum lugar, alguns anos atrás, que toda classe importada seria carregada em tempo de execução com a classe importada. Portanto, a remoção de pacotes não utilizados, especialmente pacotes inteiros, reduziria a sobrecarga de memória. Embora eu suponha que as versões modernas do java lidem com isso, então provavelmente não é mais um motivo.

E por falar nisso, com o eclipse você pode usar Ctrl+ Shift+ Opara organizar as importações, mas também pode configurar um "limpador" que lida com essas coisas (e muitas outras) cada vez que você salva um arquivo java.

Michael Zilbermann
fonte
hmm .. eu ficaria surpreso se esse fosse o comportamento .. eu sei que as classes não são inicializadas (ou seja, chamando os inicializadores estáticos) até o primeiro uso, ou até que sejam especificamente solicitadas por um carregador personalizado. mas se por "carregado" você quer dizer apenas "lido na memória, mas não processado", é possível, embora eu duvide disso.
Kip
na verdade, pensando melhor, deve ser bastante fácil de testar. compile o código com as importações não utilizadas e, em seguida, use uma ferramenta de "descompilação" e veja se as importações não utilizadas ainda estão lá ou não. caso contrário, eles estão sendo removidos pelo compilador ou estão lá apenas para a conveniência do programador.
Kip
4
Onde diabos você leu isso? É completa e totalmente incorreto, e sempre foi. Cada classe referenciada pelo código será carregada, não incluindo as importações.
Marquês de Lorne
0

Para mim, uma importação de classe não utilizada em uma classe de controlador criou um problema de compilação no build do Jenkins depois que excluí a classe importada durante a limpeza do código e confirmei a exclusão no git sem testar uma compilação local.

Aakash Kedia
fonte