una - variables estaticas java ejemplo




¿Por qué las variables estáticas son consideradas malas? (20)

si tuviera que hacer 10,000 llamadas a una función dentro de una clase, me gustaría que el método sea estático y usar un class.methodCall () directo en él en lugar de abarrotar la memoria con 10,000 instancias de la clase, ¿verdad?

Debe equilibrar la necesidad de encapsular datos en un objeto con un estado, frente a la necesidad de simplemente calcular el resultado de una función en algunos datos.

Además, las estadísticas reducen las interdependencias de las otras partes del código.

Lo mismo ocurre con la encapsulación. En aplicaciones grandes, las estáticas tienden a producir código de espagueti y no permiten fácilmente refactorización o prueba.

Las otras respuestas también proporcionan buenas razones contra el uso excesivo de estática.

Soy un programador de Java que es nuevo en el mundo corporativo. Recientemente he desarrollado una aplicación usando Groovy y Java. A lo largo del código que escribí usé una buena cantidad de estadísticas. El lote técnico superior me pidió que redujera la cantidad de estadísticas utilizadas. He buscado en Google lo mismo, y encuentro que muchos programadores están bastante en contra del uso de variables estáticas.

Las variables estáticas me parecen más cómodas de usar. Y supongo que también son eficientes (corríjame si me equivoco), porque si tuviera que hacer 10.000 llamadas a una función dentro de una clase, me gustaría que el método sea estático y utilizar una Class.methodCall() directa Class.methodCall() en él, en lugar de abarrotar la memoria con 10,000 instancias de la clase, ¿verdad?

Además, las estadísticas reducen las interdependencias de las otras partes del código. Pueden actuar como perfectos titulares estatales. Además de esto, encuentro que las estadísticas están ampliamente implementadas en algunos lenguajes como Smalltalk y Scala . Entonces, ¿por qué esta opresión por lo estático prevalece entre los programadores (especialmente en el mundo de Java)?

PD: por favor corríjame si mis suposiciones acerca de lo estático están equivocadas.


a) Motivo de los programas.

Si tiene un programa de tamaño pequeño a mediano, donde se accede a la variable estática Global.foo, la llamada a ella normalmente proviene de la nada, no hay ruta, y por lo tanto no hay una línea de tiempo, cómo la variable llega al lugar, donde se utiliza Ahora, ¿cómo sé quién lo estableció en su valor real? ¿Cómo puedo saber qué pasa si lo modifico ahora? Tengo grep sobre toda la fuente, para recopilar todos los accesos, para saber qué está pasando.

Si sabe cómo lo usa, porque acaba de escribir el código, el problema es invisible, pero si intenta entender el código extranjero, lo entenderá.

b) ¿Realmente solo necesitas uno?

Las variables estáticas a menudo evitan que varios programas del mismo tipo se ejecuten en la misma JVM con diferentes valores. A menudo no prevé usos, donde más de una instancia de su programa es útil, pero si evoluciona, o si es útil para otros, pueden experimentar situaciones en las que les gustaría iniciar más de una instancia de su programa .

Solo el código más o menos inútil que no será utilizado por muchas personas durante más tiempo de forma intensiva podría ir bien con las variables estáticas.


Como nadie * lo ha mencionado: concurrencia. Las variables estáticas pueden sorprenderte si tienes varios subprocesos que leen y escriben en la variable estática. Esto es común en las aplicaciones web (por ejemplo, ASP.NET) y puede causar algunos errores bastante enloquecedores. Por ejemplo, si tiene una variable estática que se actualiza con una página y dos personas la solicitan "casi al mismo tiempo", un usuario puede obtener el resultado esperado por el otro, o peor.

Las estadísticas reducen las interdependencias en las otras partes del código. Pueden actuar como perfectos titulares estatales.

Espero que estés preparado para usar cerraduras y lidiar con la contención.

* En realidad, Preet Sangha lo mencionó.


El mal es un término subjetivo.

No controlas lo estático en términos de creación y destrucción. Viven a instancias del programa de carga y descarga.

Dado que las estadísticas están en un solo espacio, todos los subprocesos que deseen usarlas deben pasar por el control de acceso que debe administrar. Esto significa que los programas están más acoplados y este cambio es más difícil de imaginar y administrar (como dice J Skeet). Esto conduce a problemas para aislar el impacto del cambio y, por lo tanto, afecta la forma en que se gestionan las pruebas.

Estos son los dos problemas principales que tengo con ellos.


Hay 2 problemas principales con las variables estáticas:

  • Seguridad de subprocesos: los recursos estáticos no son, por definición, seguros para subprocesos
  • Implicidad del código: no se sabe cuándo se crea una instancia de una variable estática y si se creará o no una instancia de otra variable estática

Las variables estáticas generalmente se consideran malas porque representan un estado global y, por lo tanto, son mucho más difíciles de razonar. En particular, rompen los supuestos de la programación orientada a objetos. En la programación orientada a objetos, cada objeto tiene su propio estado, representado por variables de instancia (no estáticas). Las variables estáticas representan el estado en todas las instancias, lo que puede ser mucho más difícil de probar por unidad. Esto se debe principalmente a que es más difícil aislar los cambios de las variables estáticas en una sola prueba.

Dicho esto, es importante hacer una distinción entre las variables estáticas regulares (generalmente consideradas malas) y las variables estáticas finales (constantes AKA; no tan malas).


Las variables estáticas, lo más importante, crean problemas con la seguridad de los datos (cada vez que cambian, cualquiera puede cambiar, acceso directo sin objeto, etc.)

Para más información lea this Gracias.


Me parece que estás preguntando acerca de las variables estáticas, pero también señala los métodos estáticos en tus ejemplos.

Las variables estáticas no son malas, tienen su adopción como variables globales como constantes en la mayoría de los casos combinados con el modificador final, pero como se dice no se deben usar en exceso.

Métodos estáticos también conocido como método de utilidad. Generalmente no es una mala práctica usarlos, pero la mayor preocupación es que podrían obstruct pruebas.

Como ejemplo de un gran proyecto java que usa muchas estadísticas y lo hace de forma correcta, ¡mire Play! marco También hay discussion respecto en SO.

Las variables / métodos estáticos combinados con la importación estática también se usan ampliamente en las bibliotecas que facilitan la programación declarativa en java como: lo hacen fácil o Hamcrest . No sería posible sin muchas variables y métodos estáticos.

Así que las variables estáticas (y los métodos) son buenas, ¡pero utilícelas sabiamente!


Otra razón más: la fragilidad.

Si tiene una clase, la mayoría de la gente espera poder crearla y usarla a voluntad.

Puede documentar que no es el caso, o protegerse contra él (patrón de fábrica / singleton), pero eso es un trabajo adicional y, por lo tanto, un costo adicional. Incluso entonces, en una gran empresa, es probable que alguien intente en algún momento usar su clase sin prestar atención a todos los buenos comentarios o la fábrica.

Si estás usando mucho las variables estáticas, eso se romperá. Los insectos son caros.

Entre una mejora del rendimiento de .0001% y la solidez para cambiar por parte de desarrolladores potencialmente despistados, en muchos casos la solidez es la mejor opción.


Se puede sugerir que en la mayoría de los casos en los que utiliza una variable estática, realmente desea utilizar el patrón de singleton .

El problema con los estados globales es que a veces lo que tiene sentido como global en un contexto más simple, necesita ser un poco más flexible en un contexto práctico, y aquí es donde el patrón de singleton se vuelve útil.


Las variables estáticas me parecen más cómodas de usar. Y supongo que también son eficientes (corríjame si me equivoco) porque si tuviera que hacer 10.000 llamadas a una función dentro de una clase, me gustaría que el método sea estático y usar una clase directa. en él, en lugar de abarrotar la memoria con 10,000 instancias de la clase, ¿verdad?

Veo lo que piensa, pero un patrón Singleton simple hará lo mismo sin tener que crear una instancia de 10 000 objetos.

se pueden usar métodos estáticos, pero solo para las funciones que están relacionadas con el dominio del objeto y que no necesitan o usan las propiedades internas del objeto.

ex:

public class WaterContainer {
    private int size;
    private int brand;
    ...etc

    public static int convertToGallon(int liters)...

    public static int convertToLiters(int gallon)...

}

Resumiendo algunas ventajas y desventajas básicas de usar métodos estáticos en Java:

Ventajas:

  1. Accesible globalmente, es decir, no vinculado con ninguna instancia de objeto en particular.
  2. Una instancia por JVM.
  3. Se puede acceder usando el nombre de la clase (No requiere ningún objeto).
  4. Contiene un solo valor aplicable a todas las instancias.
  5. Carga en el inicio de JVM y muere cuando JVM se apaga.
  6. No modifican el estado del objeto.

Desventajas:

  1. Los miembros estáticos son siempre parte del tiempo de memoria que están en uso o no.
  2. No se puede controlar la creación y destrucción de variables estáticas. De manera útil, se crearon en la carga del programa y se destruyeron cuando se descarga el programa (o cuando se apaga la JVM).
  3. Puede hacer que el subproceso estático sea seguro usando la sincronización, pero necesita algunos esfuerzos adicionales.
  4. Si un hilo cambia el valor de una variable estática que posiblemente pueda romper la funcionalidad de otros hilos.
  5. Debes saber "estático" antes de usarlo.
  6. No se pueden anular los métodos estáticos.
  7. La serialización no funciona bien con ellos.
  8. No participan en el polimorfismo en tiempo de ejecución.
  9. Hay un problema de memoria (hasta cierto punto, pero no mucho, supongo) si se utiliza una gran cantidad de variables / métodos estáticos. Porque no serán GC hasta que el programa termine.
  10. Los métodos estáticos también son difíciles de probar.

Creo que el uso excesivo de variables globales con palabras clave estáticas también conducirá a una pérdida de memoria en algún punto de la aplicación.


Hay dos preguntas principales en tu publicación.

Primero, sobre las variables estáticas. Las variables estáticas son totalmente innecesarias y su uso puede evitarse fácilmente. En lenguajes OOP en general, y en particular en Java, los parámetros de función se pegan por referencia, es decir, si pasa un objeto a una función, está pasando un puntero al objeto, por lo que no necesita definir variables estáticas ya que puede pasar un puntero al objeto a cualquier ámbito que necesite esta información. Incluso si esto implica que usted llenará su memoria con punteros, esto no necesariamente representará un bajo rendimiento porque los sistemas de paginación de memoria reales están optimizados para manejar esto, y mantendrán en la memoria las páginas a las que hacen referencia los punteros que pasó a la nueva alcance;el uso de variables estáticas puede hacer que el sistema cargue la página de memoria donde se almacenan cuando es necesario acceder a ellas (esto ocurrirá si no se ha accedido a la página durante mucho tiempo). Una buena práctica es poner todas esas cosas estáticas juntas en algunas pequeñas "clases de configuración", esto asegurará que el sistema lo coloque todo en la misma página de memoria.

Segundo, sobre los métodos estáticos. Los métodos estáticos no son tan malos, pero pueden reducir rápidamente el rendimiento. Por ejemplo, piense en un método que compare dos objetos de una clase y devuelva un valor que indique cuál de los objetos es más grande (método de comparación típico) este método puede ser estático o no, pero al invocarlo, la forma no estática será más eficiente ya que solo tendrá que resolver dos referencias (una para cada objeto) frente a las tres referencias que deberán resolver la versión estática del mismo método (una para la clase más dos, una para cada objeto). Pero como digo, esto no es tan malo, si echamos un vistazo a la clase de Matemáticas, podemos encontrar muchas funciones matemáticas definidas como métodos estáticos. Esto es realmente más eficiente que poner todos estos métodos en la clase que define los números,Debido a que la mayoría de ellos son raramente usados ​​e incluirlos a todos en la clase de números hará que la clase sea muy compleja y consuma muchos recursos innecesariamente.

En conclusión: evite el uso de variables estáticas y encuentre el equilibrio de rendimiento correcto cuando trate con métodos estáticos o no estáticos.

PD: perdon por mi ingles


Mi $ .02 es que varias de estas respuestas confunden el problema, en lugar de decir "lo estático es malo", creo que es mejor hablar sobre el alcance y las instancias.

Lo que diría es que una variable estática es una variable de "clase": representa un valor que se comparte en todas las instancias de esa clase. Por lo general, también se debe incluir en ese ámbito (protegido o privado a la clase y sus instancias).

Si planea poner un comportamiento de clase a su alrededor y exponerlo a otro código, entonces un singleton puede ser una mejor solución para soportar cambios en el futuro (como sugirió @Jessica). Esto se debe a que puede usar interfaces en el nivel de instancia / singleton en formas que no puede usar en el nivel de clase, en particular la herencia.

Algunas reflexiones sobre por qué creo que algunos de los aspectos de otras respuestas no son fundamentales para la pregunta ...

Las estadísticas no son "globales". En Java, el alcance se controla por separado de static / instance.

La concurrencia no es menos peligrosa para los métodos estáticos que los métodos de instancia. Todavía es el estado que necesita ser protegido. Claro que puede tener 1000 instancias con una variable de instancia cada una y solo una variable estática, pero si el acceso al código no está escrito de forma segura, todavía puede fallar, solo puede tardar un poco más en darse cuenta. .

La gestión del ciclo de vida es un argumento interesante, pero creo que es menos importante. No veo por qué es más difícil administrar un par de métodos de clase como init () / clear () que la creación y destrucción de una instancia de singleton. De hecho, algunos podrían decir que un singleton es un poco más complicado debido a GC.

PD: en términos de Smalltalk, muchos de sus dialectos tienen variables de clase, pero en Smalltalk las clases son en realidad instancias de Metaclass, así que realmente son variables en la instancia de Metaclass. Aún así, yo aplicaría la misma regla de oro. Si se están utilizando para el estado compartido entre instancias, entonces está bien. Si son compatibles con la funcionalidad pública, debería mirar un Singleton. Suspiro, seguro que echo de menos Smalltalk ...


Piense que si tiene una aplicación con muchos usuarios y ha definido un formulario estático, entonces todos los usuarios modificarán todas las demás formas de otros usuarios también.


El tema de 'Estática es malvado' es más un problema sobre el estado global. El momento adecuado para que una variable sea estática es si nunca tiene más de un estado; Las herramientas de IE que deberían ser accesibles por todo el marco y siempre devolver los mismos resultados para las mismas llamadas de métodos nunca son "malas" como las estadísticas. En cuanto a tu comentario:

Las variables estáticas me parecen más cómodas de usar. Y supongo que también son eficientes.

Las estadísticas son la opción ideal y eficiente para las variables / clases que nunca cambian .

El problema con el estado global es la incoherencia inherente que puede crear. La documentación acerca de las pruebas unitarias a menudo aborda este problema, ya que cada vez que hay un estado global al que se puede acceder por más de múltiples objetos no relacionados, sus pruebas unitarias estarán incompletas y no serán integradas por la unidad. Como se menciona en este artículo sobre el estado global y singletons , si el objeto A y B no están relacionados (ya que en uno no se hace referencia expresa a otro), A no debería poder afectar el estado de B.

Hay algunas excepciones al estado global de prohibición en un buen código, como el reloj. El tiempo es global y, en cierto sentido, cambia el estado de los objetos sin tener una relación codificada.


Las variables estáticas no son buenas ni malas. Representan atributos que describen a toda la clase y no a una instancia en particular. Si necesita tener un contador para todas las instancias de una determinada clase, una variable estática sería el lugar correcto para mantener el valor.

Los problemas aparecen cuando intenta utilizar variables estáticas para mantener valores relacionados con la instancia.


Todas las respuestas anteriores muestran por qué las estadísticas son malas. La razón por la que son malvados es porque da la falsa impresión de que está escribiendo código orientado a objetos, cuando en realidad no lo está. Eso es simplemente el mal.


todo (puede :) tiene su propósito, si tiene un montón de subprocesos que necesitan compartir / almacenar datos en caché y también toda la memoria accesible (para no dividirse en contextos dentro de una JVM) la estática es la mejor opción

-> por supuesto que puede forzar sólo una instancia, pero ¿por qué?
Encuentro algunos de los comentarios en este hilo mal, no los estáticos;)





static