Respostas:
O único problema é que ele atrapalha seu espaço de nomes local. Por exemplo, digamos que você esteja escrevendo um aplicativo Swing e, portanto java.awt.Event
, precise e também esteja em interface com o sistema de calendário da empresa com.mycompany.calendar.Event
. Se você importar os dois usando o método curinga, uma dessas três coisas acontece:
java.awt.Event
e com.mycompany.calendar.Event
, portanto, não pode nem compilar..*
), mas é a errada e luta para descobrir por que seu código está afirmando que o tipo está errado.com.mycompany.calendar.Event
, mas quando eles adicionam mais tarde, seu código válido anteriormente pára subitamente de compilar.A vantagem de listar explicitamente todas as importações é que eu posso dizer rapidamente qual classe você pretende usar, o que simplesmente facilita a leitura do código. Se você está apenas fazendo uma coisa rápida e pontual, não há nada explicitamente errado , mas os futuros mantenedores agradecerão sua clareza.
Aqui está um voto para importações em estrela. Uma declaração de importação pretende importar um pacote , não uma classe. É muito mais limpo importar pacotes inteiros; os problemas aqui identificados (por exemplo, java.sql.Date
vs java.util.Date
) são facilmente remediados por outros meios, não são realmente abordados por importações específicas e certamente não justificam importações insanamente pedantes em todas as classes. Não há nada mais desconcertante do que abrir um arquivo de origem e ter que percorrer 100 instruções de importação.
Fazer importações específicas dificulta a refatoração; se você remover / renomear uma classe, precisará remover todas as suas importações específicas. Se você alternar uma implementação para uma classe diferente no mesmo pacote, precisará corrigir as importações. Embora essas etapas extras possam ser automatizadas, elas realmente atingem a produtividade sem nenhum ganho real.
Mesmo que o Eclipse não fizesse importações de classe por padrão, todo mundo continuaria fazendo importações em estrela. Sinto muito, mas realmente não há justificativa racional para fazer importações específicas.
Veja como lidar com conflitos de classe:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Foo
, e se eu leio seu código sem usar um IDE (já que seu argumento é que eu não deveria ter que usar um), como saberei de qual pacote Foo
veio ? Claro, usando um IDE, o IDE me dirá, mas todo o seu argumento é que eu deveria poder ler o código sem um. Fazer importações explícitas ajuda a documentar o código (excelente motivo para evitar caracteres curinga) , e é muito mais provável que eu esteja lendo o código sem usar um IDE, do que escrevendo o código sem usar um IDE.
consulte o meu artigo Import on Demand is Evil
Em suma, o maior problema é que seu código pode quebrar quando uma classe é adicionada a um pacote que você importa. Por exemplo:
import java.awt.*;
import java.util.*;
// ...
List list;
No Java 1.1, tudo bem; A lista foi encontrada em java.awt e não houve conflito.
Agora, suponha que você verifique seu código que funciona perfeitamente e, um ano depois, alguém o traz para editá-lo e está usando o Java 1.2.
O Java 1.2 adicionou uma interface chamada List ao java.util. ESTRONDO! Conflito. O código que funciona perfeitamente não funciona mais.
Este é um recurso do idioma EVIL . Há NO razão que código deve parar de compilar apenas porque um tipo é adicionado a um pacote ...
Além disso, torna difícil para um leitor determinar qual "Foo" você está usando.
java.util.List
vs java.awt.List
não é tão ruim de entender, mas tente quando o nome da classe for Configuration
e várias bibliotecas de dependência o adicionaram em sua versão mais recente do repositório maven.
É não ruim para usar um wild card com uma declaração de importação Java.
Em Código Limpo , Robert C. Martin realmente recomenda usá-los para evitar longas listas de importação.
Aqui está a recomendação:
J1: Evite longas listas de importação usando caracteres curinga
Se você usar duas ou mais classes de um pacote, importe o pacote inteiro com
pacote de importação. *;
Longas listas de importações são assustadoras para o leitor. Não queremos desordenar as partes superiores dos nossos módulos com 80 linhas de importação. Em vez disso, queremos que as importações sejam uma declaração concisa sobre com quais pacotes colaboramos.
Importações específicas são dependências complexas, enquanto importações curinga não são. Se você importar especificamente uma classe, essa classe deverá existir. Mas se você importar um pacote com um curinga, nenhuma classe específica precisará existir. A declaração de importação simplesmente adiciona o pacote ao caminho de pesquisa ao procurar nomes. Portanto, nenhuma dependência verdadeira é criada por essas importações e, portanto, elas servem para manter nossos módulos menos acoplados.
Há momentos em que a longa lista de importações específicas pode ser útil. Por exemplo, se você está lidando com código legado e deseja descobrir para quais classes precisa criar zombarias e stubs, você pode percorrer a lista de importações específicas para descobrir os verdadeiros nomes qualificados de todas essas classes e depois colocar os stubs apropriados no lugar. No entanto, esse uso para importações específicas é muito raro. Além disso, a maioria dos IDEs modernos permitirá converter as importações curinga em uma lista de importações específicas com um único comando. Portanto, mesmo no caso de legado, é melhor importar caracteres curinga.
Às vezes, as importações de curingas podem causar conflitos de nome e ambiguidades. Duas classes com o mesmo nome, mas em pacotes diferentes, precisarão ser importadas especificamente ou, pelo menos, qualificadas especificamente quando usadas. Isso pode ser um incômodo, mas é raro o suficiente que o uso de importações de caracteres curinga ainda seja geralmente melhor do que importações específicas.
atuação : nenhum impacto no desempenho, pois o código de bytes é o mesmo. embora isso leve a algumas despesas gerais de compilação.
Compilação : na minha máquina pessoal, compilar uma classe em branco sem importar nada leva 100 ms, mas a mesma classe ao importar java. * Leva 170 ms.
import java.*
não importa nada. Por que isso faria diferença?
Isso atrapalha seu espaço de nome, exigindo que você especifique completamente todos os nomes de classe ambíguos. A ocorrência mais comum disso é com:
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
Também ajuda a tornar suas dependências concretas, pois todas as dependências estão listadas na parte superior do arquivo.
A maioria dos lugares em que trabalhei que usam qualquer quantidade significativa de Java faz com que importações explícitas façam parte do padrão de codificação. Às vezes, ainda uso * para prototipagem rápida e, em seguida, expanda as listas de importação (alguns IDEs também farão isso por você) ao produzir o código.
Em um projeto anterior, descobri que a mudança de importações * para importações específicas reduzia o tempo de compilação pela metade (de cerca de 10 minutos para cerca de 5 minutos). O * -import faz com que o compilador pesquise cada um dos pacotes listados para uma classe correspondente à que você usou. Embora esse tempo possa ser pequeno, ele contribui para grandes projetos.
Um efeito colateral da importação * era que os desenvolvedores copiavam e colavam linhas de importação comuns em vez de pensar no que precisavam.
No livro DDD
Seja qual for a tecnologia de desenvolvimento na qual a implementação se baseie, procure maneiras de minimizar o trabalho de refatoração de MODULES. Em Java, não há como escapar da importação para classes individuais, mas você pode pelo menos importar pacotes inteiros por vez, refletindo a intenção de que os pacotes sejam unidades altamente coesas, reduzindo simultaneamente o esforço de alterar os nomes dos pacotes.
E se ele confunde o espaço de nomes local, a culpa não é sua - culpe o tamanho do pacote.
Não há impacto no tempo de execução, pois o compilador substitui automaticamente o * por nomes de classes concretos. Se você descompilar o arquivo .class, nunca o verá import ...*
.
O C # sempre usa * (implicitamente), pois você pode apenas o using
nome do pacote. Você nunca pode especificar o nome da classe. Java introduz o recurso após c #. (Java é tão complicado em muitos aspectos, mas está além deste tópico).
No Intellij Idea, quando você "organiza importações", ele substitui automaticamente várias importações do mesmo pacote por *. Esse é um recurso obrigatório, pois você não pode desativá-lo (embora possa aumentar o limite).
O caso listado pela resposta aceita não é válido. Sem * você ainda tem o mesmo problema. Você precisa especificar o nome do pakcage no seu código, independentemente de você usar * ou não.
Para o registro: Ao adicionar uma importação, você também indica suas dependências.
Você pode ver rapidamente quais são as dependências dos arquivos (excluindo classes do mesmo espaço para nome).
O mais importante é que a importação java.awt.*
pode tornar seu programa incompatível com uma versão futura do Java:
Suponha que você tenha uma classe chamada "ABC", esteja usando o JDK 8 e importando java.util.*
. Agora, suponha que o Java 9 seja lançado e tenha uma nova classe no pacote java.util
que por coincidência também seja chamada de "ABC". Seu programa agora não será compilado no Java 9, porque o compilador não sabe se, com o nome "ABC", você quer dizer sua própria classe ou a nova classe emjava.awt
.
Você não terá esse problema quando importar apenas essas classes explicitamente java.awt
daquilo que realmente usa.
Recursos:
Stream
como um exemplo de uma nova classe adicionada em Java no java.util no Java 8 ... #
Entre todos os argumentos válidos dos dois lados, não encontrei o principal motivo para evitar o curinga: gosto de poder ler o código e saber diretamente o que são todas as classes, ou se a definição não está no idioma ou no idioma. o arquivo, onde encontrá-lo. Se mais de um pacote for importado com *, preciso procurar em cada um deles para encontrar uma classe que não reconheço. A legibilidade é suprema e eu concordo que o código não deve exigir um IDE para lê-lo.