2009-12-31 16 views
17

¿Por qué Eclipse tiene un enfoque de grano fino al importar tipos? En C# estoy acostumbrado a cosas como "usar System.Windows.Controls" y terminar con esto, pero Eclipse prefiere importar cada widget que hago referencia individualmente (usando el atajo Ctrl + Shift + O). ¿Hay algún daño al importar un espacio de nombres completo si sé que necesitaré varios tipos en él?Eclipse/Java: ¿es dañino importar java. (Namespace). *?

+0

También puede organizar las importaciones al guardarlas sin necesidad de presionar 'Ctrl + Shift + O' cada vez. Marque "Guardar acciones" en las preferencias. – BalusC

+0

Esta es una opción que puede cambiar en Eclipse y otros IDEs. –

+0

posible duplicado de [¿Por qué es malo usar una tarjeta salvaje con una sentencia de importación Java?] (Http://stackoverflow.com/questions/147454/why-is-using-a-wild-card-with-a-java- import-statement-bad) – jvnill

Respuesta

10

El único daño que pueden causar las importaciones de paquetes comodín es una mayor probabilidad de colisiones de espacios de nombres si hay múltiples clases del mismo nombre en varios paquetes.

Digamos, por ejemplo, que quiero programar para usar la clase ArrayList de Java Collections Framework en una aplicación AWT que usa un componente de interfaz gráfica de usuario List para mostrar información. En aras de un ejemplo, supongamos que tenemos la siguiente:

// 'ArrayList' from java.util 
ArrayList<String> strings = new ArrayList<String>(); 

// ... 

// 'List' from java.awt 
List listComponent = new List() 

Ahora, con el fin de utilizar lo anterior, no tendría que ser una importación de esas dos clases, mínimamente:

import java.awt.List; 
import java.util.ArrayList; 

Ahora, si tuviéramos que usar un comodín en el paquete import, tendríamos lo siguiente.

import java.awt.*; 
import java.util.*; 

Sin embargo, ahora tendremos un problema!

Hay una clase java.awt.List y una java.util.List, por lo que referirse a la clase List sería ambiguo. Habría que hacer referencia a la List con un nombre de clase completo si queremos eliminar la ambigüedad:

import java.awt.*; 
import java.util.*; 

ArrayList<String> strings = new ArrayList<String>(); 

// ... 

// 'List' from java.awt -- need to use a fully-qualified class name. 
java.awt.List listComponent = new java.awt.List() 

Por lo tanto, hay casos en los que utilizan un paquete de comodín import puede llevar a problemas.

+0

¿Son las colisiones del espacio de nombres lo suficientemente comunes en Java que consideraría una buena práctica no importar * espacios de nombres? –

+1

@James: las colisiones de espacio de nombres en Java son extremadamente comunes. Mucho más que C#. Cuanto mayor sea la precisión, mejor, en mi opinión. – Alohci

+0

No muy a menudo; depende de las API con las que estés trabajando. Pero nunca debes escribir una importación manualmente, y Eclipse las retira para que no las veas, ¡así que no me preocuparía! :) –

5

No creo que las importaciones de comodines tengan algún tipo de implicaciones de rendimiento (y si lo hace, creo que solo ocurrirá en tiempo de compilación). Pero como esto SO post points out, es posible que pueda tener superposiciones de nombre de clase si los usa.

Solo uso Ctrl + Espacio para forzar la importación cuando estoy usando una clase que aún no se ha importado, y la importación se realiza automáticamente. Luego presiono Ctrl + Shift + O después de refactorizar una clase para eliminar las importaciones que ya no se utilizan.

12

Alguien puede leer su código sin IDE; en este caso, las importaciones no comodín le ayudarán a determinar qué clases se utilizan en su código.

+1

Sin embargo, esto solo es cierto si cada actualización posterior del archivo también actualiza la lista de importación de manera apropiada. No es probable que los conservadores que no usan un IDE sepan cuándo deben eliminarse las declaraciones de importación, ya que no es un error dejarlos allí. Así que, en realidad, es más probable que el usuario no IDE descubra cuál es la clase usado para hacer. – Mocky

0

No hace daño al código. Como principio general, ¿por qué importar algo si no vas a utilizar?

+5

En respuesta a su pregunta, incluyo la última oración de la pregunta original: * ¿Hay algún daño al importar un espacio de nombre completo si sé que necesitaré varios tipos en él? * – jball

+0

Buena respuesta, +1. – fastcodejava

15

Eclipse tiene una configuración excelente llamada "Organizar importaciones" en el diálogo Ventana -> Preferencias que le permite decir cuando N clases se utilizan desde un paquete, haga una importación de comodín. Lo uso en N = 2 o 3 por lo general.

+1

¡Oh genial! No sabía que existía. –

+1

Sí, también lo tienen para las importaciones "estáticas", pero ¿quién realmente usa esos de todos modos?) –

+2

¡Cualquiera que use las anotaciones de JUnit 4! –

2

Hasta el JDK 1.2 este código compilarse bien:

import java.awt.*; 
import java.util.*; 

public class Foo 
{ 
    // List is java.awt.List 
    private List list; 
} 

en el JDK 1.2 se añadió java.util.List y el código ya no se compilan porque el compilador no sabía lo que era buscado Lista (AWT o util).Puede solucionarlo agregando "import java.awt.List;" al final de las importaciones, pero el punto es que tienes que hacer algo para arreglarlo.

Yo personalmente uso la única importación en lugar de la importación a la carta por dos razones:

  1. está claro dónde viene cada clase de
  2. si tiene un gran número de importaciones la clase probablemente esté haciendo demasiado y se debe dividir. Es un "olor a código".
1

Desde un punto de vista purista, cada importación crea una dependencia y un potencial de conflicto. Las importaciones se tratan como un mal necesario para que se minimicen. Importar otro paquete con un * es como escribir un cheque en blanco. Importar dos paquetes como ese es como dar acceso a alguien para mover dinero entre sus cuentas.

Desde un punto de vista práctico, esto a menudo tiene sentido porque diferentes proyectos y bibliotecas utilizan nombres sorprendentemente similares para diferentes conceptos. O imagínese que importa todo del paquete A y luego todo lo del paquete B, y usa algo de la clase C del paquete B. Si más adelante alguien agrega una clase con el nombre C al paquete A, ¡es posible que su código se rompa!

Habiendo dicho eso, admito que soy flojo. A menudo pre-importo todo en el paquete, y luego dejo que Eclipse me organice según lo que realmente uso.

1

No importa si se importan todas las clases en un paquete/espacio de nombres, pero creo que es mejor incluir cada clase individual. Hace las cosas más claras para los desarrolladores que vienen detrás de ti exactamente de dónde viene cada clase.

No es un problema si está usando un IDE capaz como IntelliJ. Me imagino que Eclipse y NetBeans también pueden administrar importaciones. Agregará el código y colapsará de la vista para que no atempere la ventana. ¿Qué podría ser más fácil?

0

Si se escribe algo de código Java como

LinkedList<foo> llist = new LinkedList<foo>() 

y no ha importado ListaEnlazada a su proyecto, Eclipse le preguntará si desea importarlo. Como solo está utilizando LinkedList y nada más, solo importará LinkedList. Si hace algo más en el mismo proyecto, como
ArrayList<foo> alist = new ArrayList<foo>()

Luego Eclipse también dirá que necesita importar ArrayList, pero nada más. Eclipse solo importa lo que necesita en función de las llamadas a la biblioteca que haya realizado. Si necesita varios tipos o elementos de la misma biblioteca, no hay daño en el uso de un

import java.namespace.*

a seguir adelante y traer a los otros elementos que necesita. A Eclipse no le importará mientras importe los paquetes y bibliotecas que contienen los elementos a los que hace referencia, tales como escáneres, listas enlazadas, etc.

Desde una perspectiva de legibilidad, es una pregunta diferente. Si desea que las personas sepan exactamente qué es exactamente lo que está importando, entonces llamar a cada widget o paquete podría estar en orden. Esto puede ser bastante tedioso si usa muchas funciones diferentes del mismo paquete en la biblioteca estándar y puede hacer que los encabezados de los archivos sean bastante largos, por lo tanto, el comodín *.No importa si se importa mediante comodines, realmente se reduce a sus estándares de codificación y qué tan transparente quiere que sean sus encabezados de clase.

8

La directiva import es un compilador Directiva, se le indica al compilador dónde buscar una clase y permite no tener que utilizar siempre nombres de clase completos, por ejemplo java.util.HashMap. Pero las directivas de importación en sí mismas no se colocan en los archivos de códigos de bytes compilados, el compilador compila el nombre completo en el archivo .class.

Cuando se utiliza sin un comodín, la directiva explícitamente le dice al compilador que busque un archivo específico en el classpath. Con un comodín, la directiva le dice al compilador que busque el paquete nombrado y para buscar en ese paquete las posibles coincidencias cada vez que se necesite emparejar un nombre. La última versión probablemente tomará (un poco) más tiempo para el compilador que la anterior.

En otras palabras, la directiva import no puede afectar runtime ejecución de código de ninguna manera. Sin embargo, la directiva import afecta el tiempo de compilación. Además, encuentro que usar import con comodines hace que el código sea menos legible.

En realidad, la cuestión cost of import statements del mes en el javaperformancetuning.com perfectamente resumir esto en su conclusión:

  • No hay costo de ejecución del uso de una declaración de importación
  • El proceso de compilación puede tomar un poco más tiempo con una importación instrucción
  • El proceso de compilación puede llevar incluso más tiempo con un comodín import instrucción
  • para mejorar la legibilidad, las declaraciones de importación comodín son una mala práctica para nada pero las clases de usar y tirar
  • La sobrecarga recopilación de declaraciones de importación no comodín son menor, pero dan la legibilidad beneficios por lo que la mejor práctica es utilizar ellos
0

La importación de cada clase explícitamente proporciona una unión dura entre el nombre corto (ej. Proxy) y el nombre largo (por ejemplo, java.lang.reflect.Proxy), en lugar del enlace suelto que dice que probablemente haya uno en java.lang.reflect.*, java.io.* o java.net.* o en algún otro lugar de las importaciones de comodines que tenga.

Esto puede ser un problema si por alguna razón otra clase llamado Proxy aparece en algún lugar de java.io.* o java.net.* o en su propio código, como el compilador entonces no sabe qué clase de proxy que desea, ya que tendría si explícitamente importado java.lang.reflect.Proxy.

El ejemplo anterior no es contrived. La clase java.net.Proxy se introdujo en Java 5 y habría roto su código si se escribió como se indicó anteriormente. Consulte la explicación oficial de Sun sobre cómo eludir los problemas de comodines en http://java.sun.com/j2se/1.5.0/compatibility.html

(La importación de comodines es solo un mecanismo de conveniencia para quienes no usan un IDE para mantener los estados de importación.Si usa un IDE, permítale que lo ayude :)