Recientemente estuve revisando mis advertencias en Eclipse y me encontré con esta:
Dará una advertencia al compilador si el método se puede declarar como estático.
[editar] Cita exacta en la ayuda de Eclipse, con énfasis en privado y final:
Cuando está habilitado, el compilador emitirá un error o una advertencia para los métodos que son privados o finales y que se refieren solo a miembros estáticos.
Sí, sé que puedo apagarlo, pero quiero saber la razón para encenderlo.
¿Por qué sería bueno declarar todos los métodos posibles como estáticos?
¿Dará esto algún beneficio de rendimiento? (en un dominio móvil)
Al señalar un método como estático, supongo que muestra que no usa ninguna variable de instancia, por lo tanto, ¿podría moverse a una clase de estilo utils?
Al final del día, ¿debería simplemente desactivar esta opción 'ignorar' o debería corregir las más de 100 advertencias que me ha dado?
¿Crees que estas son solo palabras clave adicionales que ensucian el código, ya que el compilador simplemente insertará estos métodos de todos modos? (como si no declararas todas las variables que puedes finalizar pero podrías ).
fuente
Respuestas:
Siempre que escribe un método, cumple un contrato en un ámbito determinado. Cuanto más estrecho sea el alcance, menor será la posibilidad de que escriba un error.
Cuando un método es estático, no puede acceder a miembros no estáticos; por lo tanto, su alcance es más estrecho. Entonces, si no necesita y nunca necesitará (incluso en subclases) miembros no estáticos para cumplir con su contrato, ¿por qué dar acceso a estos campos a su método? Declarar el método
static
en este caso permitirá que el compilador verifique que no use miembros que no pretenda usar.Y además, ayudará a las personas que lean su código a comprender la naturaleza del contrato.
Por eso se considera bueno declarar un método
static
cuando en realidad está implementando un contrato estático.En algunos casos, su método solo significa algo relativo a una instancia de su clase, y sucede que su implementación en realidad no usa ningún campo o instancia no estático. En tales casos, no marcaría el método
static
.Ejemplos de dónde no usaría la
static
palabra clave:fuente
private
método pudiera declararse estático, casi invariablemente debería serlo. Para cualquier otro nivel de acceso, hay otros factores a considerar, como el envío dinámico.object.method()
por seleccionar el método a llamar.Aquí no hay ningún concepto con optimización.
Un
static
método sestatic
debe a que declaras explícitamente que el método no depende de ninguna instancia de la clase adjunta solo porque no es necesario. Entonces esa advertencia de Eclipse, como se indica en la documentación:Si no necesita ninguna variable de instancia y su método es privado (no se puede llamar desde fuera) o final (no se puede anular), entonces no hay razón para dejar que sea un método normal en lugar de uno estático. Un método estático es intrínsecamente más seguro incluso porque se le permite hacer menos cosas con él (no necesita ninguna instancia, no tiene ningún
this
objeto implícito ).fuente
No tengo información sobre el rendimiento, supongo que es un poco mejor como mucho, ya que el código no necesita realizar un envío dinámico según el tipo.
Sin embargo, un argumento mucho más fuerte en contra de la refactorización en métodos estáticos es que actualmente el uso de estático se considera una mala práctica. Los métodos / variables estáticos no se integran bien en un lenguaje orientado a objetos y, además, son difíciles de probar correctamente. Esta es la razón por la que algunos lenguajes más nuevos renuncian por completo al concepto de métodos / variables estáticos, o intentan internalizarlo en el lenguaje de una manera que funcione mejor con OO (por ejemplo, Objetos en Scala).
La mayoría de las veces, necesita métodos estáticos para implementar funciones que solo usan parámetros como entrada y producen una salida usando eso (por ejemplo, funciones de utilidad / ayuda) En los lenguajes modernos, hay un concepto de función de primera clase que permite eso, tan estático no es necesario. Java 8 tendrá expresiones lambda integradas, por lo que ya nos estamos moviendo en esta dirección.
fuente
private static
métodos para que no tenga que burlarse de ellos1. Método de declaración
static
proporciona un ligero beneficio de rendimiento, pero lo que es más útil, permite usarlo sin tener una instancia de objeto a mano (piense, por ejemplo, en el método de fábrica o en obtener un singleton). También sirve al propósito documental de contar la naturaleza del método. Este propósito documental no debe ignorarse, ya que da una pista inmediata sobre la naturaleza del método a los lectores del código y a los usuarios de la API y también sirve como una herramienta de pensamiento para el programador original: ser explícito sobre el significado deseado ayuda también piensa con claridad y produce código de mejor calidad (creo que basado en mi experiencia personal, pero las personas son diferentes). Por ejemplo, es lógico y, por lo tanto, deseable distinguir entre métodos que operan en un tipo y métodos que actúan en una instancia del tipo (como lo señalaJon Skeet en su comentario a una pregunta de C # ).Otro caso de uso más de los
static
métodos es imitar la interfaz de programación de procedimientos. Piense en lajava.lang.System.println()
clase y sus métodos y atributos. La clasejava.lang.System
se utiliza como un espacio de nombres de agrupación en lugar de un objeto instanciable.2. ¿Cómo puede Eclipse (o cualquier otra entidad programada o de otro tipo, biocomponible o no biocomponible) saber con certeza qué método podría declararse estático? Incluso si una clase base no accede a variables de instancia o llama a métodos no estáticos, por el mecanismo de herencia las cosas pueden cambiar. Solo si el método no se puede anular heredando la subclase, podemos afirmar con un 100% de certeza que el método realmente se puede declarar
static
. Anular un método es imposible exactamente en los dos casos de serprivate
(ninguna subclase puede usarlo directamente y ni siquiera en principio lo sabe), ofinal
(incluso si es accesible por la subclase, no hay forma de cambiar el método para hacer referencia a funciones o datos de instancia).De ahí la lógica de la opción Eclipse.
3. El póster original también pregunta: "¿ Señalar un método como estático, supongo que está mostrando que no usa ninguna variable de instancia, por lo tanto, podría ser movido a una clase de estilo utils? " Este es un muy buen punto. A veces, este tipo de cambio de diseño se indica mediante una advertencia.
Es una opción muy útil, que personalmente me aseguraría de habilitar si tuviera que usar Eclipse y programar en Java.
fuente
Vea la respuesta de Samuel sobre cómo cambia el alcance del método. Supongo que este es el aspecto principal de convertir un método en estático.
También preguntaste sobre el rendimiento:
Puede haber una pequeña ganancia de rendimiento, porque una llamada a un método estático no necesita la referencia implícita "this" como parámetro.
Sin embargo, este impacto en el rendimiento es realmente mínimo. Por lo tanto, se trata del alcance.
fuente
De las pautas de rendimiento de Android:
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
fuente
Bueno, la documentación de Eclipse dice sobre la advertencia en cuestión:
Creo que prácticamente lo dice todo. Si el método es privado y final y solo se refiere a miembros estáticos, el método en cuestión también podría declararse estático y, por lo tanto, hacer evidente que solo pretendemos acceder a contenido estático desde él.
Honestamente, no creo que haya ninguna otra razón misteriosa detrás de esto.
fuente
Me faltaban algunos números para las diferencias de velocidad. Así que intenté compararlos, lo que resultó no ser tan fácil: ¿el bucle de Java se vuelve más lento después de algunas ejecuciones / falla de JIT?
Finalmente usé Caliper y los resultados son los mismos que ejecutar mis pruebas a mano:
No hay una diferencia medible para llamadas estáticas / dinámicas. Al menos no para Linux / AMD64 / Java7.
Los resultados de Caliper están aquí: https://microbenchmarks.appspot.com/runs/1426eac9-36ca-48f0-980f-0106af064e8f#r:scenario.benchmarkSpec.methodName,scenario.vmSpec.options.CMSLargeCoalSurplusPercent,scenarioop.vm. CMSLargeSplitSurplusPercent, escenario.vmSpec.options.CMSSmallCoalSurplusPercent, escenario.vmSpec.options.CMSSmallSplitSurplusPercent, escenario.vmSpec.options.FLSLargestBlockCoalesceProximity, escenario.vmSpec.Pec.opciones.
y mis propios resultados son:
La clase Caliper Test fue:
Y mi propia clase de prueba fue:
fuente
Los métodos que puede declarar como estáticos son los que no requieren instanciación, como
Que luego puede llamar a cambio en cualquier otra clase sin instanciar esa clase.
... Pero eso es algo que probablemente ya sepa. No le brinda ningún beneficio real per se, aparte de dejar más claro que el método no usa ninguna variable de instancia.
En otras palabras, puede apagarlo completamente de manera más segura. Si sabe que nunca usará un método en otras clases (en cuyo caso debería ser privado), no necesita que sea estático en absoluto.
fuente