Variables estáticas vs instancias: ¿diferencia?

¿Cuál es la diferencia entre una variable estática y de instancia? La siguiente oración es lo que no puedo entender:

En ciertos casos, todos los objetos de una clase deben compartir una sola copia de una variable en particular; aquí se usa una variable estática.
Una variable estática representa toda la información de toda la clase. Todos los objetos de una clase comparten los mismos datos.

Pensé que los vars de instancia se usaban en toda la clase, mientras que las variables estáticas solo tenían scope dentro de sus propios métodos.

En el contexto de los atributos de clase, la static tiene un significado diferente. Si tiene un campo como:

 private static int sharedAttribute; 

luego, cada instancia de la clase compartirá la misma variable, de modo que si la cambia en una instancia, el cambio se reflejará en todas las instancias, creadas antes o después del cambio.

Dicho esto, puede comprender que esto es malo en muchos casos, porque fácilmente puede convertirse en un efecto secundario no deseado: el cambio de objeto a también afecta a b y usted podría terminar preguntándose por qué b cambió sin razones aparentes. De todos modos, hay casos en que este comportamiento es absolutamente deseable:

  1. constantes de clase: ya que son const , tener todas las clases de acceso al mismo valor no hará daño, porque nadie puede cambiar eso. También pueden ahorrar memoria, si tienes muchas instancias de esa clase. Sin embargo, no estoy seguro acerca del acceso concurrente .
  2. variables que están destinadas a ser compartidas, tales como contadores de referencia & co.

static vars static se instancian antes de que se inicie el progtwig, por lo que si tiene demasiados, podría ralentizar el inicio.

Un método static solo puede acceder a static atributos static , pero piénselo dos veces antes de intentar esto.

Regla de oro: no use static , a menos que sea necesario y sepa lo que está haciendo o declare una clase constante.

Diga que hay una clase de prueba:

 class Test{ public static int a = 5; public int b = 10; } // here t1 and t2 will have a separate copy of b // while they will have same copy of a. Test t1 = new test(); Test t2 = new test(); 

Puedes acceder a una variable estática con su clase Nombre como este

 Test.a = 1//some value But you can not access instance variable like this System.out.println(t1.a); System.out.println(t2.a); 

En ambos casos, la salida será igual a 1 en todas las instancias de la clase de prueba. mientras que la variable de instancia tendrá cada una una copia separada de b (variable de instancia) Entonces

  t1.b = 15 // will not be reflected in t2. System.out.println(t1.b); // this will print 15 System.out.println(t2.b); / this will still print 10; 

Espero que explique tu consulta.

Las variables de clase solo tienen una copia que comparten todos los diferentes objetos de una clase, mientras que cada objeto tiene su propia copia personal de una variable de instancia. Por lo tanto, las variables de instancia en diferentes objetos pueden tener valores diferentes, mientras que las variables de clase en diferentes objetos pueden tener solo un valor.

Variables de instancia :

Estas variables pertenecen a la instancia de una clase, por lo tanto, un objeto. Y cada instancia de esa clase (objeto) tiene su propia copia de esa variable. Los cambios realizados en la variable no se reflejan en otras instancias de esa clase.

 public class Product { public int barcode; } 

Variables de clase :

También se conocen como variables de miembros estáticos y solo hay una copia de esa variable que se comparte con todas las instancias de esa clase. Si se realizan cambios en esa variable, todas las demás instancias verán el efecto de los cambios.

 public class Product { public static int barcode; } 

Ejemplo completo:

Variables de instancia :

 public class Main { public static void main(String[] args) { Product prod1 = new Product(); prod1.barcode = 123456; Product prod2 = new Product(); prod2.barcode = 987654; System.out.println(prod1.barcode); System.out.println(prod2.barcode); } } public class Product { public int barcode; } 

El resultado será:

123456
987654

Ahora, cambie la variable de instancia a una variable de clase haciéndola estática:

Variables de clase :

 public class Main { public static void main(String[] args) { Product prod1 = new Product(); prod1.setBarcode(123456); Product prod2 = new Product(); prod2.setBarcode(987654); System.out.println(prod1.getBarcode()); System.out.println(prod2.getBarcode()); } } public class Product { public static int barcode; public int getBarcode() { return barcode; } public void setBarcode(int value){ barcode = value; } } 

Utilicé métodos no estáticos para obtener y establecer el valor de Barcode para poder llamarlo desde el objeto y no desde la clase.
La salida será siguiente:

987654
987654

Las variables estáticas (clase) y las variables de instancia son variables miembro porque ambas están asociadas a una clase específica, pero la diferencia entre ellas es que las variables de clase solo tienen una copia que comparten todos los diferentes objetos de una clase, mientras que cada objeto tiene es una copia personal de una variable de instancia. Por lo tanto, las variables de instancia en diferentes objetos pueden tener valores diferentes, mientras que las variables de clase en diferentes objetos pueden tener solo un valor.

Las variables de instancia contienen valores a los que se debe hacer referencia mediante más de un método, constructor o bloque, o partes esenciales del estado de un objeto que deben estar presentes en toda la clase. La variable estática solo sería una copia de cada variable de clase por clase, independientemente de cuántos objetos se creen a partir de ella.

Creo que estás pensando en la definición de C / C ++ de la palabra clave estática. Allí, la palabra clave estática tiene muchos usos. En Java, la funcionalidad de la palabra clave estática se describe en su publicación. De todos modos, puedes intentarlo por ti mismo:

 public class Test_Static{ static int x; public static void main(String[] argv){ Test_Static a = new Test_Static(); Test_Static b = new Test_Static(); ax = 1; // This will give an error, but still compile. bx = 2; System.out.println(ax); // Should print 2 } } 

y de manera similar para variables no estáticas:

 public class Test_NonStatic{ int x; public static void main(String [] argv){ Test_NonStatic a = new Test_NonStatic(); Test_NonStatic b = new Test_NonStatic(); ax = 1; bx = 2; System.out.println(ax); // Should print 1. } } 

Considere una clase MyClass , que tiene un miembro estático y uno no estático:

 public class MyClass { public static int STATICVARIABLE = 0; public int nonStaticVariable = 0; } 

Ahora, creemos un main() para crear un par de instancias:

 public class AnotherClass{ public static void main(String[] args) { // Create two instances of MyClass MyClass obj1 = new MyClass(); MyClass obj2 = new MyClass(); obj1.nonStaticVariable = 30; // Setting value for nonstatic varibale obj1.STATICVARIABLE = 40; //Setting value for static variable obj2.nonStaticVariable = 50; obj2.STATICVARIABLE = 60; // Print the values actually set for static and non-static variables. System.out.println(obj1.STATICVARIABLE); System.out.println(obj1.nonStaticVariable); System.out.println(obj2.STATICVARIABLE); System.out.println(obj2.nonStaticVariable); } } 

Resultado:

 60 30 60 50 

Ahora puede ver el valor de la variable estática impresa 60 ambas veces, ya que tanto obj1 como obj2 se referían a la misma variable. Con la variable no estática, las salidas difieren, ya que cada objeto creado crea su propia copia de variable no estática; los cambios realizados en ellos no afectan a la otra copia de la variable creada por otro objeto.