Variabili statico vs istanza: differenza?

Qual è la differenza tra una variabile statica e una istanza. La seguente frase è ciò che non riesco a ottenere:

In alcuni casi, solo una copia di una particolare variabile deve essere condivisa da tutti gli oggetti di una class, in questo caso viene utilizzata una variabile statica.
Una variabile statica rappresenta informazioni di class. Tutti gli oggetti di una class condividono gli stessi dati.

Pensavo che le vars delle istanze fossero usate in class mentre le variabili statiche avevano solo un ambito nei loro stessi metodi?

Nel contesto degli attributi di class, la static ha un significato diverso. Se hai un campo come:

 private static int sharedAttribute; 

quindi, ogni istanza della class condividerà la stessa variabile, in modo che se la si modifica in un’istanza, la modifica rifletterà in tutte le istanze, create prima o dopo la modifica.

Detto questo, potresti capire che questo è sbagliato in molti casi, perché può facilmente trasformarsi in un indesiderato effetto collaterale: cambiare object a interessa anche b e potresti finire per chiedermi perché è cambiato senza ragioni apparenti. Ad ogni modo, ci sono casi in cui questo comportamento è assolutamente desiderabile:

  1. costanti di class: dato che sono const , avere tutte le classi che accedono allo stesso valore non danneggerà, perché nessuno può cambiarlo. Possono anche risparmiare memoria, se hai molte istanze di quella class. Non sono sicuro dell’accesso concorrente , comunque.
  2. variabili che devono essere condivise, come contatori di riferimento e co.

static vars static vengono istanziati prima dell’avvio del programma, quindi se ne possiedi troppi, puoi rallentare l’avvio.

Un metodo static può accedere solo agli attributi static , ma pensaci due volte prima di provare questo.

Regola pratica: non usare la static , a meno che non sia necessario e tu sai cosa stai facendo o stai dichiarando una costante di class.

Diciamo che c’è una class di test:

 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(); 

Puoi accedere a una variabile statica con il suo nome di class come questo

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

In entrambi i casi l’output sarà 1 come una condivisione per tutte le istanze della class di test. mentre la variabile d’istanza avrà ciascuno una copia separata di b (variabile d’istanza) So

  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; 

Spero che questo spieghi la tua domanda.

Le variabili di class hanno solo una copia condivisa da tutti i diversi oggetti di una class, mentre ogni object ha la sua copia personale di una variabile di istanza. Quindi, le variabili di istanza tra diversi oggetti possono avere valori diversi, mentre le variabili di class tra diversi oggetti possono avere un solo valore.

Variabili di istanza :

Queste variabili appartengono all’istanza di una class, quindi a un object. E ogni istanza di quella class (object) ha la propria copia di quella variabile. Le modifiche apportate alla variabile non si riflettono in altre istanze di quella class.

 public class Product { public int barcode; } 

Variabili di class :

Queste sono anche conosciute come variabili membro statiche e c’è solo una copia di quella variabile che è condivisa con tutte le istanze di quella class. Se vengono apportate modifiche a tale variabile, tutte le altre istanze vedranno l’effetto delle modifiche.

 public class Product { public static int barcode; } 

Esempio completo:

Variabili di istanza :

 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; } 

L’output sarà:

123456
987654

Ora, modifica la variabile di istanza in una variabile di class rendendola statica:

Variabili di class :

 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; } } 

Ho usato metodi non statici per ottenere e impostare il valore di Barcode per poterlo chiamare dall’object e non dalla class.
L’output seguirà:

987654
987654

Le variabili statiche (di class) e le variabili di istanza sono entrambe variabili membro perché sono entrambe associate a una class specifica, ma la differenza tra di esse è che le variabili di class hanno solo una copia condivisa da tutti gli oggetti di una class, mentre ogni object ha è la propria copia personale di una variabile di istanza. Quindi, le variabili di istanza tra diversi oggetti possono avere valori diversi, mentre le variabili di class tra diversi oggetti possono avere un solo valore.

Le variabili dell’istanza contengono valori che devono essere referenziati da più di un metodo, costruttore o blocco, o parti essenziali dello stato di un object che devono essere presenti in tutta la class. La variabile statica sarebbe solo una copia di ogni variabile di class per class, indipendentemente dal numero di oggetti creati da essa.

Penso che tu stia pensando alla definizione di C / C ++ della parola chiave static. Lì, la parola chiave static ha molti usi. In Java, la funzionalità della parola chiave statica è descritta nel tuo post. In ogni caso, puoi provarlo tu stesso:

 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 } } 

e allo stesso modo per le variabili non statiche:

 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. } } 

Considera una class MyClass , con un membro statico e uno non statico:

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

Ora, creiamo un main() per creare un paio di istanze:

 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); } } 

Risultato:

 60 30 60 50 

Ora puoi vedere il valore della variabile statica stampata 60 entrambe le volte, poiché sia obj1 che obj2 si riferivano alla stessa variabile. Con la variabile non statica, gli output differiscono, poiché ogni object creato crea una propria copia di variabile non statica; le modifiche apportate a loro non hanno alcun impatto sull’altra copia della variabile creata da un altro object.