¿Por qué es malo utilizar un comodín con una declaración de importación de Java?
Es mucho más conveniente y claro utilizar una sola declaración como
import java.awt.*;
que importar un montón de clases individuales
import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...
¿Qué hay de malo en utilizar un comodín en la import
declaración?
El único problema es que satura su espacio de nombres local. Por ejemplo, digamos que estás escribiendo una aplicación Swing y, por lo tanto, necesitas java.awt.Event
, y también estás interactuando con el sistema de calendario de la empresa, que tiene com.mycompany.calendar.Event
. Si importa ambos usando el método comodín, sucede una de estas tres cosas:
- Tiene un conflicto de nombres absoluto entre
java.awt.Event
ycom.mycompany.calendar.Event
y, por lo tanto, ni siquiera puede compilar. - En realidad, solo logra importar uno (solo uno de sus dos importaciones lo hace
.*
), pero es el incorrecto y le cuesta descubrir por qué su código afirma que el tipo es incorrecto. - Cuando compila su código, no hay ningún archivo
com.mycompany.calendar.Event
, pero cuando luego agregan uno, su código previamente válido deja de compilarse repentinamente.
La ventaja de enumerar explícitamente todas las importaciones es que puedo saber de un vistazo qué clase desea utilizar, lo que simplemente facilita mucho la lectura del código. Si solo está haciendo algo rápido y puntual, no hay nada explícitamente incorrecto , pero los futuros mantenedores le agradecerán su claridad.
Aquí hay una votación a favor de las importaciones estrella. Una declaración de importación tiene como objetivo importar un paquete , no una clase. Es mucho más limpio importar paquetes completos; Los problemas identificados aquí (por ejemplo, java.sql.Date
vs. java.util.Date
) se solucionan fácilmente por otros medios, no se abordan realmente mediante importaciones específicas y ciertamente no justifican importaciones increíblemente pedantes en todas las clases. No hay nada más desconcertante que abrir un archivo fuente y tener que revisar 100 declaraciones de importación.
Realizar importaciones específicas dificulta la refactorización; Si elimina/cambia el nombre de una clase, debe eliminar todas sus importaciones específicas. Si cambia una implementación a una clase diferente en el mismo paquete, debe arreglar las importaciones. Si bien estos pasos adicionales se pueden automatizar, en realidad son golpes de productividad sin ningún beneficio real.
Si Eclipse no importara clases específicas de forma predeterminada, todos seguirían realizando importaciones de estrellas. Lo siento, pero en realidad no existe una justificación racional para realizar importaciones específicas.
Aquí se explica cómo lidiar con los conflictos de clases:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Consulte mi artículo Importar bajo demanda es malo
En resumen, el mayor problema es que su código puede fallar cuando se agrega una clase a un paquete que importa. Por ejemplo:
import java.awt.*;
import java.util.*;
// ...
List list;
En Java 1.1, esto estaba bien; La lista se encontró en java.awt y no hubo ningún conflicto.
Ahora supongamos que verifica su código que funciona perfectamente y, un año después, alguien más lo saca para editarlo y está usando Java 1.2.
Java 1.2 agregó una interfaz llamada Lista a java.util. ¡AUGE! Conflicto. El código que funciona perfectamente ya no funciona.
Esta es una característica del lenguaje MALVADO . NO hay ninguna razón por la que el código deba dejar de compilarse solo porque se agrega un tipo a un paquete...
Además, al lector le resulta difícil determinar qué "Foo" está utilizando.
No está mal utilizar un comodín con una declaración de importación de Java.
En Clean Code , Robert C. Martin recomienda usarlos para evitar largas listas de importación.
Aquí está la recomendación:
J1: Evite listas de importación largas mediante el uso de comodines
Si usa dos o más clases de un paquete, importe el paquete completo con
importar paquete.*;
Las largas listas de importaciones resultan desalentadoras para el lector. No queremos saturar la parte superior de nuestros módulos con 80 líneas de importaciones. Más bien queremos que las importaciones sean una declaración concisa sobre con qué paquetes colaboramos.
Las importaciones específicas son dependencias estrictas, mientras que las importaciones comodín no lo son. Si importa específicamente una clase, entonces esa clase debe existir. Pero si importa un paquete con un comodín, no es necesario que existan clases particulares. La declaración de importación simplemente agrega el paquete a la ruta de búsqueda cuando busca nombres. Por lo tanto, dichas importaciones no crean una verdadera dependencia y, por lo tanto, sirven para mantener nuestros módulos menos acoplados.
Hay ocasiones en las que la larga lista de importaciones específicas puede resultar útil. Por ejemplo, si está trabajando con código heredado y desea saber para qué clases necesita crear simulacros y apéndices, puede recorrer la lista de importaciones específicas para encontrar los verdaderos nombres calificados de todas esas clases y luego colocar los talones apropiados en su lugar. Sin embargo, este uso para importaciones específicas es muy raro. Además, la mayoría de los IDE modernos le permitirán convertir las importaciones con comodines en una lista de importaciones específicas con un solo comando. Entonces, incluso en el caso heredado, es mejor importar comodines.
Las importaciones de comodines a veces pueden provocar ambigüedades y conflictos de nombres. Será necesario importar específicamente dos clases con el mismo nombre, pero en paquetes diferentes, o al menos calificarlas específicamente cuando se utilicen. Esto puede ser una molestia, pero es lo suficientemente raro como para que el uso de importaciones comodín sea generalmente mejor que las importaciones específicas.
Rendimiento : no hay impacto en el rendimiento ya que el código de bytes es el mismo. aunque generará algunos gastos generales de compilación.
Compilación : en mi máquina personal, compilar una clase en blanco sin importar nada tarda 100 ms, pero la misma clase al importar java.* tarda 170 ms.