2010-10-18 7 views
12

¿Cómo y dónde debemos usar un modificador estático para:¿Cómo y dónde usar el modificador estático en Java?

1. Campo y
2. Método?

Para example en java.lang.Math clase, los métodos campos como abs(), atan(), cos(), etc son estáticos, es decir que se puede acceder a: Math.abs()

Pero por qué es una buena práctica?

Digamos, no lo mantengo estático y creo un objeto de la clase y accedo a él, que de todas formas puedo, solo recibiré una advertencia de que estás intentando acceder a un método estático de una manera no estática (como lo señala @duffymo, no en el caso de la clase de Matemáticas).

ACTUALIZACIÓN 1:

Así, método de utilidad, debe ser estática, es decir, cuyo trabajo es sólo depende de los parámetros del método. Entonces, por ejemplo, ¿el método updateString(String inputQuery, String highlightDoc) debería haber sido un método estático en this question?

Respuesta

20

Puede pensar en un método o campo "estático" como si fuera declarado fuera de la definición de la clase. En otras palabras

  1. Solo hay una 'copia' de un campo/método estático.
  2. Los campos/métodos estáticos no pueden acceder a campos/métodos no estáticos.

Hay varias instancias en las que desea hacer algo estático.

El ejemplo canónico para un campo es crear un campo entero estático que mantenga un recuento en todas las instancias (objetos) de una clase. Además, los objetos singleton, por ejemplo, también suelen emplear el modificador estático.

De forma similar, los métodos estáticos se pueden usar para realizar trabajos 'de utilidad' para los que se pasan todas las dependencias necesarias como parámetros del método; no se puede hacer referencia a la palabra clave 'this' dentro de un método estático.

En C#, también puede tener clases estáticas que, como se puede adivinar, contienen sólo los miembros estáticos:

public static class MyContainer 
{ 
    private static int _myStatic; 

    public static void PrintMe(string someString) 
    { 
     Console.Out.WriteLine(someString); 
     _myStatic++; 
    } 

    public static int PrintedInstances() 
    { 
     return _myStatic; 
    } 
} 
+0

por favor revise mi actualización. ¿Puedes darnos alguna información sobre el método de ejemplo que publiqué en mi pregunta? Que también es un método de utilidad – zengr

+0

@zengr: Sí, haría ese método estático. Puede imaginar, por ejemplo, una clase StringHelper que incluya todas las operaciones de manipulación de Cadenas específicas de la aplicación (como la realizada por ese método). De hecho, pondría _any_ method static si no hace referencia a la palabra clave 'this'; no es necesario crear una copia de este método en cada objeto, es más legible de esta manera, y es bueno para la claridad del diseño general de OMI. – Alex

1

Por lo general, cuando el método sólo depende de los parámetros de la función y no en el estado interno de la objeto es un método estático (con singleletone es la única excepción). No puedo imaginar dónde se usan realmente los campos estáticos (son los mismos que las variables globales que deben evitarse).
Como en su ejemplo, las funciones matemáticas solo dependen de los parámetros.

+1

Existen usos perfectamente legítimos para el modificador estático, como los enumerados en mi respuesta. – Alex

+0

"son lo mismo que variables globales que deben evitarse", no si son definitivas; esos aparecen a menudo como constantes de clase. –

+0

@alex No he pensado en eso. Supongo que el uso de campos estáticos depende en gran medida de tu forma de programar y probablemente existan situaciones perfectamente adecuadas para usarlos (y que no son singletone de ninguna manera). El hecho de que todavía no los haya visto no significa que existan o que sean malos :) Por mi propio interés, ¿podría explicarme por qué querría saber el número total de instancias de un objeto pero sin referencia a él? – Fge

0

No se puede crear una instancia de java.lang.Math; no hay un constructor público

Inténtelo:

public class MathTest 
{ 
    public static void main(String [] args) 
    { 
     Math math = new Math(); 

     System.out.println("math.sqrt(2) = " + math.sqrt(2)); 
    } 
} 

Esto es lo que obtendrá:

C:\Documents and Settings\Michael\My Documents\MathTest.java:5: Math() has private access in java.lang.Math 
     Math math = new Math(); 
        ^
1 error 

Tool completed with exit code 1 
+0

Vaya, lo extrañé. Pero, en general, si un método es estático, de todos modos podemos acceder a él usando un objeto. Entonces, ¿dónde entra la eficiencia de la memoria al usar estática? – zengr

+1

No es una cuestión de eficiencia de memoria; se trata de la intención del diseñador de la clase. – duffymo

1

Para un campo que debe ser conservado estática si desea que todas las instancias de una clase determinada para tener acceso a su valor. Por ejemplo si tengo

public static int age = 25; 

Entonces, cualquier instancia de la clase se puede obtener o establecer el valor de la edad con todas apuntando al mismo valor. Si crea algo estático, corre el riesgo de tener dos instancias sobrescribiendo los valores de los demás y posiblemente causando problemas. El motivo para crear métodos estáticos es principalmente para la función de utilidad donde se transfieren todos los datos requeridos para el método y no desea tomar el control de crear una instancia de la clase cada vez que desee llamar al método.

8

Static usa menos memoria ya que existe solo una vez por Classloader.

Tener métodos estáticos puede ahorrar algo de tiempo, ya que no tiene que crear un objeto primero para que pueda invocar una función. Puedes/deberías usar métodos estáticos cuando están más o menos por sí mismos (es decir, Math.abs (X) - realmente no hay ningún objeto que la función necesite). Básicamente es una cosa de conveniencia (al menos hasta donde yo lo veo - otros podrían y no estarían de acuerdo: P)

Los campos estáticos realmente deberían usarse con precaución. Hay bastantes patrones que necesitan campos estáticos ... pero lo básico primero:

un campo estático existe solo una vez. Así que si usted tiene una clase simple (un poco pseudocódigo):

class Simple { 
static int a; 
int b; 
} 

y ahora a tomar objetos con:

Simple myA = new Simple(); 
Simple myB = new Simple(); 
myA.a = 1; 
myA.b = 2; 
myB.a = 3; 
myB.b = 4; 
System.out.println(myA.a + myA.b + myB.a + myB.b); 

obtendrá 3234 - porque mediante el establecimiento de myB.a en realidad se sobrescribe myA.a también porque a es estático. Existe en un lugar en la memoria.

Normalmente desea evitar esto porque pueden ocurrir cosas realmente extrañas. Pero si buscas en google por ejemplo para Factory Pattern, verás que en realidad hay usos bastante útiles para este comportamiento.

Espero que aclare un poco.

+1

Los campos estáticos existen una vez por cargador de clases, no una vez por JVM. – user82928

2

Pruebe echar un vistazo a esta publicación, sino que también da algunos ejemplos de cuándo y cuándo no usar modificadores estáticos y finales.

La mayoría de las publicaciones anteriores son similares, pero esta publicación podría ofrecer alguna otra información.
When to use Static Modifiers

Cuestiones relacionadas