Acabo de recibir un comentario de revisión de que mi importación estática del método no era una buena idea. La importación estática era de un método de una clase DA, que tiene principalmente métodos estáticos. Entonces, en medio de la lógica de negocios, tuve una actividad da que aparentemente parecía pertenecer a la clase actual:
import static some.package.DA.*;
class BusinessObject {
void someMethod() {
....
save(this);
}
}
El revisor no estaba interesado en cambiar el código y no lo hice, pero estoy de acuerdo con él. Una razón dada para no importar estáticamente fue que era confuso el lugar donde se definió el método, no estaba en la clase actual y no en ninguna superclase, por lo que es demasiado tiempo para identificar su definición (el sistema de revisión basado en la web no tiene clics) enlaces como IDE :-) Realmente no creo que esto importe, las importaciones estáticas todavía son bastante nuevas y pronto todos nos acostumbraremos a localizarlas.
Pero la otra razón, con la que estoy de acuerdo, es que una llamada a un método no calificado parece pertenecer al objeto actual y no debe saltar los contextos. Pero si realmente perteneciera, tendría sentido extender esa superclase.
Entonces, ¿cuándo tiene sentido los métodos de importación estáticos? Cuando lo has hecho ¿Te gustó / te gusta cómo se ven las llamadas no calificadas?
EDITAR: La opinión popular parece ser que los métodos de importación estática si nadie los va a confundir como métodos de la clase actual. Por ejemplo, métodos de java.lang.Math y java.awt.Color. Pero si abs y getAlpha no son ambiguos, no entiendo por qué readEmployee sí lo es. Como en muchas opciones de programación, creo que esto también es una preferencia personal.
Gracias por su respuesta chicos, estoy cerrando la pregunta.
fuente
import static
, la característica esstatic import
Respuestas:
Esto es de la guía de Sun cuando lanzaron la función (énfasis en el original):
( https://docs.oracle.com/javase/8/docs/technotes/guides/language/static-import.html )
Hay dos partes que quiero mencionar específicamente:
extend some.package.DA
? Si es así, las importaciones estáticas pueden ser una forma más limpia de manejar esto. Si nunca hubiera soñado con extendersome.package.DA
, entonces este es probablemente un mal uso de las importaciones estáticas. No lo use solo para guardar algunos caracteres al escribir.import static some.package.DA.save
lugar deDA.*
. Eso hará que sea mucho más fácil encontrar de dónde proviene este método importado.Personalmente, he usado esta característica del lenguaje muy raramente, y casi siempre solo con constantes o enumeraciones, nunca con métodos. La compensación, para mí, casi nunca vale la pena.
fuente
Otro uso razonable para las importaciones estáticas es con JUnit 4. En versiones anteriores de los métodos JUnit, como
assertEquals
yfail
se heredaron desde que se extendió la clase de pruebajunit.framework.TestCase
.En JUnit 4, las clases de prueba ya no necesitan extenderse
TestCase
y en su lugar pueden usar anotaciones. Luego puede importar estáticamente los métodos de aserción desdeorg.junit.Assert
:JUnit documentos utilizándolo de esta manera.
fuente
Effective Java, segunda edición , al final del artículo 19 notas que se pueden utilizar las importaciones estáticas si usted se encuentra en gran medida el uso de las constantes de una clase de utilidad. Creo que este principio se aplicaría a las importaciones estáticas de constantes y métodos.
Tiene sus ventajas y desventajas. Hace que el código sea un poco más legible a costa de perder información inmediata sobre dónde se define el método. Sin embargo, un buen IDE le permitirá ir a la definición, por lo que este no es un gran problema.
Todavía debe usar esto con moderación, y solo si se encuentra usando cosas del archivo importado muchas, muchas veces.
Editar: actualizado para ser más específico a los métodos, ya que a eso se refiere esta pregunta. El principio se aplica independientemente de lo que se importe (constantes o métodos).
fuente
UtilityClassWithFrequentlyUsedMethods
necesita ser acortado.double myPI = Math.PI;
y luego puedo seguir refiriéndome enmyPI
lugar deMath.PI
.Estoy de acuerdo en que pueden ser problemáticos desde una perspectiva de legibilidad y deben usarse con moderación. Pero cuando se usa un método estático común, en realidad pueden aumentar la legibilidad. Por ejemplo, en una clase de prueba JUnit, los métodos como
assertEquals
son obvios de dónde provienen. Del mismo modo para los métodos dejava.lang.Math
.fuente
sin x cos y + cos x sin y
. En Java se convierte en:Math.sin(x) * Math.cos(y) + Math.cos(x) * Math.sin(y)
. Horrible de leer.using
directiva en C ++: pueden ser locales .Creo que la importación estática es realmente útil para eliminar nombres de clase redundantes cuando se usan clases de utilidades como
Arrays
yAssertions
.No estoy seguro de por qué, pero Ross omitió la última oración que menciona esto en la documentación a la que hace referencia .
Básicamente copiado de este blog: https://medium.com/alphadev-thoughts/static-imports-are-great-but-underused-e805ba9b279f
Así por ejemplo:
Afirmaciones en pruebas
Este es el caso más obvio en el que creo que todos estamos de acuerdo.
Clases de utilidades y enumeraciones
El nombre de la clase se puede eliminar en muchos casos cuando se utilizan clases de utilidades que hacen que el código sea más fácil de leer
El paquete java.time tiene algunos casos en los que debería usarse
Ejemplo de cuándo no usar
fuente
Lo uso mucho para Color.
Es muy poco probable que los colores se confundan con algo más.
fuente
Recomiendo el uso de importación estática cuando se utiliza OpenGL con Java, que es un caso de uso caer en el "uso intensivo de las constantes de una clase de utilidad" categoría
Considere eso
le permite portar el código C original y escribir algo legible como:
en lugar de esa fealdad generalizada común:
fuente
Las importaciones estáticas son la única característica "nueva" de Java que nunca he usado y que no pretendo usar, debido a los problemas que acaba de mencionar.
fuente
Utilizo 'import static java.lang.Math. *' Al portar código pesado matemático de C / C ++ a java. Los métodos matemáticos se asignan del 1 al 1 y facilitan la diferenciación del código portado sin la calificación del nombre de la clase.
fuente
Encontré que esto es muy conveniente cuando utilizo las clases de utilidad.
Por ejemplo, en lugar de usar:
if(CollectionUtils.isNotEmpty(col))
En cambio puedo:
Qué IMO aumenta la legibilidad del código cuando uso esta utilidad varias veces en mi código.
fuente
Hablando de pruebas de unidad: la mayoría de las personas utilizan las importaciones estáticas para los diversos métodos estáticos que burlones marcos proporcionan, tales como
when()
overify()
.Y, por supuesto, cuando se utiliza la única afirmación de que debería estar utilizándola
assertThat()
, resulta útil importar de forma estática los emparejadores de hachas, como en:fuente
Son útiles para reducir la palabrería, particularmente en los casos en que se llaman muchos métodos importados, y la distinción entre métodos locales e importados es clara.
Un ejemplo: código que involucra múltiples referencias a java.lang.Math
Otro: una clase de constructor XML donde anteponer el nombre de clase a cada referencia ocultaría la estructura que se está construyendo
fuente
Creo que las importaciones estáticas están ordenadas para NLS en el estilo gettext.
Esto marca la cadena como una cadena que debe extraerse y proporciona una manera fácil y limpia de reemplazar la cadena con su traducción.
fuente
La importación estática de IMO es una característica bastante agradable. Es absolutamente cierto que la gran dependencia de la importación estática hace que el código sea ilegible y difícil de entender a qué clase pertenece un método o atributo estático. Sin embargo, en mi experiencia se convierte en una característica utilizable, especialmente al diseñar
Util
clases que proporcionan algunos métodos y atributos estáticos. La ambigüedad que surge cada vez que se proporciona importación estática se puede eludir estableciendo estándares de código. En mi experiencia dentro de una empresa, este enfoque es aceptable y hace que el código sea más limpio y fácil de entender. Preferiblemente inserto el_
carácter en métodos estáticos frontales y atributos estáticos (de alguna manera adoptado de C). Aparentemente, este enfoque viola los estándares de nomenclatura de Java, pero proporciona claridad al código. Por ejemplo, si tenemos una clase AngleUtils:En este caso, la importación estática proporciona claridad y la estructura del código me parece más elegante:
De inmediato, alguien puede saber qué método o atributo proviene de una importación estática y oculta la información de la clase a la que pertenece. No sugiero usar la importación estática para clases que son parte integral de un módulo y proporcionan métodos estáticos y no estáticos, ya que en este caso es importante saber qué clase proporciona cierta funcionalidad estática.
fuente
H_
para las importaciones de unaHelper
clase de utilidad que tengo, oC_
paraCommon
, oU_
paraUtility
. Alternativamente, he considerado usar nombres de clase de uno o dos caracteres para estas clases ampliamente utilizadas, pero me preocupaba que a veces pudieran entrar en conflicto con los nombres locales: tener algún código heredado con nombres de métodos en mayúsculas.Debe usarlos cuando:
switch
declaración con valores de enumeraciónfuente
Los uso cuando puedo. Tengo la configuración de IntelliJ para recordarme si lo olvido. Creo que se ve mucho más limpio que un nombre de paquete totalmente calificado.
fuente