¿Alguna razón para limpiar las importaciones no utilizadas en Java, además de reducir el desorden?

99

¿Existe alguna buena razón para evitar declaraciones de importación no utilizadas en Java? Según tengo entendido, están ahí para el compilador, por lo que muchas importaciones no utilizadas no tendrán ningún impacto en el código compilado. ¿Es solo para reducir el desorden y evitar conflictos de nombres en el futuro?

(Lo pregunto porque Eclipse da una advertencia sobre las importaciones no utilizadas, lo cual es un poco molesto cuando estoy desarrollando código porque no quiero eliminar las importaciones hasta que esté bastante seguro de haber terminado de diseñar la clase).

Dormir
fuente

Respuestas:

86

No creo que haya problemas de rendimiento o algo por el estilo si no está eliminando las importaciones.

Pero podría haber conflictos de nombres, en casos excepcionales, como importar la interfaz de lista.

En Eclipse siempre puede usar un atajo (depende del SO - Win: Ctrl + SHIFT + Oy Mac :) COMMAND + SHIFT + Opara organizar las importaciones. Luego, Eclipse limpia la sección de importación elimina todas las importaciones obsoletas, etc. Si necesita una cosa importada nuevamente, eclipse la agregará automáticamente mientras completa la declaración con Ctrl + SPACE. Por lo tanto, no es necesario mantener el código no utilizado en su clase.

Como siempre, el código no utilizado lo distraerá a usted y a otras personas mientras lee el código y deja algo en su código activo porque tal vez lo necesite más tarde se considera una mala práctica.

Janusz
fuente
22
En realidad, es Ctrl + Shift + O en Windows.
Matt Ball
1
Ctrl + Shift + O en linux bien. Probablemente lo mismo en BSD.
WhyNotHugo
2
Otra forma de acceder a la acción de organizar importaciones es haciendo clic ctrl+3(al menos en windwos) y luego escribiendo importaciones. Obviamente, es más lento que ctrl + shift + O, pero es una forma de encontrarlo rápidamente (y muchas otras acciones que recuerdas o simplemente estás tratando de encontrar) incluso si no recuerdas el atajo específico para esto.
epeleg
53

Una sería que si elimina la clase a la que hace referencia la importación de la ruta de clases, no obtendrá un error tonto del compilador que no sirvió para nada. Y no obtendrá falsos positivos cuando realice una búsqueda "dónde se usa".

Otro (pero esto sería de naturaleza muy específica) sería si la importación no utilizada tuviera conflictos de nomenclatura con otra importación, lo que le haría usar nombres completamente calificados innecesariamente.

Anexo: Hoy, el servidor de compilación comenzó a fallar en la compilación (ni siquiera en la ejecución de prueba) con un error de memoria insuficiente. Funcionó bien para siempre y los registros no tuvieron ningún cambio en el proceso de compilación o adiciones significativas que pudieran explicar esto. Después de intentar aumentar la configuración de la memoria (¡esto es ejecutar una JVM de 64 bits en un CentOS de 64 bits!) A algo mucho más allá de donde los clientes podrían compilar, examiné los registros uno por uno.

Hubo una importación incorrecta que un desarrollador había usado y abandonado (usaron la clase, la importaron automáticamente y luego se dieron cuenta de que era un error). Esa importación no utilizada extrajo un nivel completamente separado de la aplicación que, si bien el IDE no está configurado para separarlos, el proceso de compilación sí lo es. Esa única importación arrastró tantas clases que el compilador intentó compilar sin tener las bibliotecas dependientes relevantes en la ruta de clases, que esto causó tantos problemas que causó el error de falta de memoria. Tomó una hora resolver este problema causado por una importación no utilizada.

Yishai
fuente
4
@Yishai, si usa Eclipse, busque acciones de guardado, que pueden normalizar el código fuente cada vez que guarde.
Thorbjørn Ravn Andersen
2
@EJP, aunque no afectan el código de bytes resultante, el compilador debe resolverlos para comprender el código de bytes que necesita crear.
Yishai
3
@EJP, todo el apéndice habla del tiempo de compilación ("el servidor de compilación comenzó a fallar en la compilación").
Yishai
1
¿Todavía no entiendo cómo la importación por sí sola podría causar todo esto?
Thorbjørn Ravn Andersen
1
@Yishai Lo siento, pero no lo creo. Ha diagnosticado mal esto. La importación no debería tener tal efecto, a menos que la clase se haya utilizado realmente. Todo lo que hace la declaración de importación es decirle al compilador en qué paquete está esa clase. El compilador sólo intenta compilar implícitamente cuando necesita información de tipo sobre esa clase.
Marqués de Lorne
9

Desde un punto de vista purista, cualquier dependencia es una "restricción" del producto y, por lo tanto, puede causar problemas de mantenimiento más adelante.

Por ejemplo, supongamos que su programa usa la clase com.XYZObjectPool, y que luego decide no usarla pero nunca eliminar la importación. Si alguien más ahora quiere crear una instancia de org.WVYObjectPool y solo hacer referencia a ObjectPool, no recibe ninguna advertencia al respecto hasta que en algún lugar de la línea haya un problema de conversión o de invocación.

Este no es, por cierto, un escenario poco realista. Cada vez que Eclipse le preguntaba qué versión específica de X deseaba importar, y elegía uno de entre muchos paquetes, es un escenario en el que si ha tenido la importación allí, es posible que haya obtenido la elección incorrecta sin saberlo.

De cualquier manera, puede pedirle a Eclipse que los limpie por usted

Uri
fuente
3

¿Advertencia? Pídale a Eclipse que los limpie automáticamente. Eso es lo que hace IntelliJ. Si es lo suficientemente inteligente para advertirle, debería ser lo suficientemente inteligente como para limpiarlos. Recomiendo buscar una configuración de Eclipse para decirle que deje de ser tan molesto y haga algo.

duffymo
fuente
4
Eso es guardar acciones. Personalmente, me gusta que Eclipse solo cambie su código cuando lo haya solicitado explícitamente.
Thorbjørn Ravn Andersen
1
@ Thorbjørn: De acuerdo, especialmente si es una clase que dejé de usar por un tiempo pero que espero volver a agregar en breve.
Donal Fellows
2
@Donal, bueno, para eso es Ctrl-Space.
Thorbjørn Ravn Andersen
3

Esto tiene que ver con la claridad del programa útil para el mantenimiento.

Si tuviera que mantener un programa, encontrará lo útil que es tener una sola importación de clase por línea.

Piense en el siguiente escenario:

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
     }
 }

Cuando corrige errores o mantiene un fragmento de código (o solo lo lee) es muy útil para el lector saber a qué paquete pertenecen las clases utilizadas. Usar la importación de comodines como se muestra arriba no ayuda para ese propósito.

Incluso con un IDE, no desea desplazarse o saltar a la declaración y regresar, es más fácil si comprende en términos de funcionalidad de qué otros paquetes y clases depende el código actual.

Si esto es para un proyecto personal o algo pequeño, realmente no importa, pero para algo más grande que debe ser utilizado por otros desarrolladores (y mantenido a lo largo de los años), es algo que DEBE TENER.

No hay absolutamente ninguna diferencia de rendimiento con ninguno.

OscarRyz
fuente
3

Para su información, esto me sorprendió, ya que no pensé que organizar las importaciones en realidad eliminara las importaciones no utilizadas, pensé que simplemente las clasificó.

Eliminar automáticamente las importaciones durante una operación de guardado me causó cierto dolor cuando, por ejemplo, durante el desarrollo o las pruebas, tienes un problema y comentas algún código, cuando lo guardas, se eliminan las importaciones utilizadas por la sección comentada del código. A veces esto no es un problema ya que puede deshacer ( Ctrl+ Z) los cambios, pero otras veces no es tan simple como puede haber hecho otros cambios. También tuve un problema en el que cuando descomentaba el código (ya lo había comentado y luego lo había guardado, eliminando así las importaciones de ese código), automáticamente intentaba adivinar las importaciones que se necesitaban y recogía las incorrectas (por ejemplo, creo que tenía una StringUtilsclase en uso y eligió otra con el mismo nombre de la biblioteca incorrecta).

Prefiero organizar las importaciones manualmente en lugar de tenerlo como una acción de guardado.

Juan
fuente
2

Para eclipse, uso esto: ventana -> preferencias -> java -> editor -> guardar acción -> marque la casilla de verificación para organizar las importaciones (también hay muchas otras cosas útiles allí, como formatear, hacer que los campos sean finales, etc. .). Entonces, cuando guardo mi archivo, eclipse elimina las importaciones unessacry para mí. En mi opinión, si no necesita algo, elimínelo (o deje que eclipse lo elimine).

kukudas
fuente
2

Puede comentar las declaraciones de importación no utilizadas y las advertencias no le molestarán, pero puede ver lo que tenía.

Sharon
fuente
2
@DimaSan En realidad, sí: la pregunta dice que no quiero eliminar las importaciones hasta que esté bastante seguro de haber terminado de diseñar la clase.
The Vee
1

No hay ningún impacto en el rendimiento, aunque para mejorar la legibilidad, puede hacerlo limpio. Eliminar las importaciones no utilizadas es bastante simple tanto en Eclipse como en IntelliJ IDEA.

Eclipse

Windows / Linux -    Ctrl+ Shift+O

Mac -                        Cmd+ Shift+O

IntelliJ IDEA o Android Studio

Windows / Linux -    Ctrl+ Alt+O

Mac -                        Cmd+ Alt+O

Madan Sapkota
fuente
0

Leí en alguna parte, hace algunos años, que cada clase importada se cargaría en tiempo de ejecución con la clase de importación. Por lo tanto, eliminar paquetes no utilizados, especialmente paquetes completos, reduciría la sobrecarga de memoria. Aunque supongo que las versiones modernas de Java tratan con eso, probablemente ya no sea una razón.

Y, por cierto, con eclipse puede usar Ctrl+ Shift+ Opara organizar las importaciones, pero también puede configurar un "limpiador" que se ocupe de esas cosas (y muchas otras) cada vez que guarde un archivo java.

Michael Zilbermann
fuente
hmm ... me sorprendería si ese fuera el comportamiento ... sé que las clases no se inicializan (es decir, llaman a los inicializadores estáticos) hasta el primer uso, o hasta que son solicitadas específicamente por un cargador personalizado. pero si por "cargado" te refieres a "leído en la memoria pero no procesado", es posible, aunque lo dudo.
Kip
en realidad, pensándolo bien, debería ser bastante fácil de probar. compile el código con las importaciones no utilizadas, luego use una herramienta de "descompilación" y vea si las importaciones no utilizadas todavía están ahí o no. si no es así, el compilador los está eliminando o simplemente están ahí para conveniencia del programador.
Kip
4
¿Dónde diablos leíste eso? Es total y absolutamente incorrecto, y siempre lo ha sido. Se cargarán todas las clases a las que hace referencia el código , sin incluir las importaciones.
Marqués de Lorne
0

Para mí, una importación de clase no utilizada en una clase de controlador creó un problema de compilación en la compilación de Jenkins después de que eliminé la clase importada durante la limpieza del código y cometí la eliminación en git sin probar una compilación en local.

Aakash Kedia
fuente