Cosa fa la parola chiave ‘statica’ in una class?

Per essere precisi, stavo provando questo codice:

package hello; public class Hello { Clock clock = new Clock(); public static void main(String args[]) { clock.sayTime(); } } 

Ma ha dato l’errore

Imansible accedere al campo non statico nel metodo statico principale

Quindi ho cambiato la dichiarazione clock in questo modo:

 static Clock clock = new Clock(); 

E ha funzionato. Cosa significa mettere quella parola chiave prima della dichiarazione? Cosa farà esattamente e / o restringerà in termini di ciò che può essere fatto a quell’object?

static membri static appartengono alla class anziché a un’istanza specifica.

Significa che esiste solo un’istanza di un campo static [1] anche se crei un milione di istanze della class o non ne crei nessuna. Sarà condiviso da tutte le istanze.

Poiché anche i metodi static non appartengono a un’istanza specifica, non possono fare riferimento ai membri dell’istanza (come sapresti a quale class dell’istanza Hello desideri fare riferimento?). static membri static possono solo fare riferimento a membri static . I membri delle istanze possono, naturalmente, accedere ai membri static .

Nota a margine: naturalmente, static membri static possono accedere ai membri di un’istanza tramite un riferimento a un object .

Esempio:

 public class Example { private static boolean staticField; private boolean instanceField; public static void main(String[] args) { // a static method can access static fields staticField = true; // a static method can access instance fields through an object reference Example instance = new Example(); instance.instanceField = true; } 

[1]: A seconda delle caratteristiche di runtime, può essere uno per ClassLoader o AppDomain o thread, ma questo è accanto al punto.

Significa che c’è una sola istanza di “clock” in Hello, non una per ogni istanza separata della class “Hello”, o più, quindi significa che ci sarà un riferimento “clock” comunemente condiviso tra tutte le istanze di la class “Hello”.

Quindi se dovessi fare un “nuovo Ciao” in qualsiasi parte del tuo codice: A- nel primo scenario (prima della modifica, senza usare “statico”), farebbe un nuovo orologio ogni volta che viene chiamato un “nuovo Ciao”, ma B- nel secondo scenario (dopo la modifica, usando “statico”), ogni istanza “new Hello” continuerà a condividere e utilizzare lo stesso iniziale “clock” di riferimento creato per primo.

A meno che tu non abbia bisogno di un “orologio” da qualche parte al di fuori del main, ciò funzionerebbe altrettanto bene:

 package hello; public class Hello { public static void main(String args[]) { Clock clock=new Clock(); clock.sayTime(); } } 

La parola chiave static indica che qualcosa (un campo, un metodo o una class nidificata) è correlato al tipo piuttosto che a una particolare istanza del tipo. Ad esempio, si chiama Math.sin(...) senza alcuna istanza della class Math e in effetti non è ansible creare un’istanza della class Math .

Per ulteriori informazioni, consultare il bit relativo del tutorial Java di Oracle .


Nota a margine

Sfortunatamente, Java consente di accedere ai membri statici come se fossero membri di istanze, ad es

 // Bad code! Thread.currentThread().sleep(5000); someOtherThread.sleep(5000); 

Questo fa sembrare che sleep sia un metodo di istanza, ma in realtà è un metodo statico: fa sempre dormire il thread corrente. È meglio mettere in chiaro questo nel codice di chiamata:

 // Clearer Thread.sleep(5000); 

La parola chiave static in Java indica che la variabile o la funzione è condivisa tra tutte le istanze di quella class in quanto appartiene al tipo , non gli oggetti veri e propri.

Quindi se hai una variabile: private static int i = 0; e lo si incrementa ( i++ ) in un’istanza, la modifica si rifletterà in tutte le istanze. ora sarò 1 in tutti i casi.

I metodi statici possono essere utilizzati senza creare un’istanza di un object.

Utilizzo di base di membri statici …

 public class Hello { // value / method public static String staticValue; public String nonStaticValue; } class A { Hello hello = new Hello(); hello.staticValue = "abc"; hello.nonStaticValue = "xyz"; } class B { Hello hello2 = new Hello(); // here staticValue = "abc" hello2.staticValue; // will have value of "abc" hello2.nonStaticValue; // will have value of null } 

Ecco come puoi avere valori condivisi in tutti i membri della class senza inviare l’istanza di class Hello all’altra class. E con statico non è necessario creare un’istanza di class.

 Hello hello = new Hello(); hello.staticValue = "abc"; 

Puoi semplicemente chiamare valori o metodi statici per nome della class:

 Hello.staticValue = "abc"; 

Statico significa che non è necessario creare un’istanza della class per utilizzare i metodi o le variabili associate alla class. Nel tuo esempio, puoi chiamare:

 Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class 

direttamente, invece di:

 Hello h = new Hello(); h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable 

Dall’interno di un metodo statico (che appartiene a una class) non è ansible accedere a membri che non sono statici, poiché i loro valori dipendono dall’istanza della class. Un object Clock non statico, che è un membro di istanza, avrebbe un valore / riferimento diverso per ciascuna istanza della class Hello e, pertanto, non è ansible accedervi dalla parte statica della class.

Statico in Java:

Statico è un modificatore di non accesso. La parola chiave static appartiene alla class dell’istanza della class. può essere usato per colbind una variabile o un metodo a una class.

La parola chiave statica può essere utilizzata con:

Metodo

Variabile

Classe annidata all’interno di un’altra class

Blocco di inizializzazione

NON POSSONO essere utilizzato con:

Classe (non annidata)

Costruttore

interfacce

Metodo Local Inner Class (Differenza quindi class annidata)

Metodi di class interiore

Variabili di istanza

Variabili locali

Esempio:

Immagina il seguente esempio che ha una variabile di istanza denominata conteggio incrementata nel costruttore:

 package pkg; class StaticExample { int count = 0;// will get memory when instance is created StaticExample() { count++; System.out.println(count); } public static void main(String args[]) { StaticExample c1 = new StaticExample(); StaticExample c2 = new StaticExample(); StaticExample c3 = new StaticExample(); } } 

Produzione:

1 1 1

Poiché la variabile di istanza ottiene la memoria al momento della creazione dell’object, ogni object avrà la copia della variabile di istanza, se viene incrementata, non rifletterà su altri oggetti.

Ora se cambiamo il conteggio delle variabili di istanza in uno statico, il programma produrrà un output diverso:

 package pkg; class StaticExample { static int count = 0;// will get memory when instance is created StaticExample() { count++; System.out.println(count); } public static void main(String args[]) { StaticExample c1 = new StaticExample(); StaticExample c2 = new StaticExample(); StaticExample c3 = new StaticExample(); } } 

Produzione:

1 2 3

In questo caso, la variabile statica otterrà la memoria solo una volta, se qualsiasi object modifica il valore della variabile statica, manterrà il suo valore.

Statico con finale:

La variabile globale dichiarata come definitiva e statica rimane invariata per l’intera esecuzione. Perché, i membri statici sono memorizzati nella memoria della class e vengono caricati una sola volta durante l’intera esecuzione. Sono comuni a tutti gli oggetti della class. Se dichiari le variabili statiche come definitive, qualsiasi object non può cambiarne il valore in quanto è definitivo. Pertanto, le variabili dichiarate come definitive e statiche sono a volte indicate come costanti. Tutti i campi di interfaccia sono indicati come costanti, poiché sono definitivi e statici per impostazione predefinita.

inserisci la descrizione dell'immagine qui

Risorsa immagine: statico finale

Questa discussione ha finora ignorato le considerazioni sul classloader. A rigor di termini, i campi statici Java sono condivisi tra tutte le istanze di una class per un determinato programma di caricamento classi.

Per aggiungere alle risposte esistenti, lasciami provare con una foto:

Un tasso di interesse del 2% viene applicato a TUTTI i conti di risparmio. Quindi è statico .

Un equilibrio dovrebbe essere individuale , quindi non è statico.

inserisci la descrizione dell'immagine qui

Un campo può essere assegnato alla class o a un’istanza di una class. Per impostazione predefinita i campi sono variabili di istanza. Usando static il campo diventa una variabile di class, quindi c’è un solo clock . Se apporti modifiche in un posto, è visibile ovunque. Le variabili di istanza vengono modificate indipendentemente l’una dall’altra.

In Java, la parola chiave static può essere semplicemente considerata come indicante quanto segue:

“senza riguardo o relazione con nessuna particolare istanza”

Se pensi di static in questo modo, diventa più facile comprenderne l’uso nei vari contesti in cui si trova:

  • Un campo static è un campo che appartiene alla class piuttosto che a una particolare istanza

  • Un metodo static è un metodo che non ne ha idea; è definito sulla class e non conosce alcuna particolare istanza di quella class a meno che non venga passato un riferimento ad essa

  • Una class membro static è una class nidificata senza alcuna nozione o conoscenza di un’istanza della sua class di inclusione (a meno che non venga passato un riferimento a un’istanza di class che lo include)

Statico rende il membro di clock un membro della class invece di un membro di istanza. Senza la parola chiave static dovresti creare un’istanza della class Hello (che ha una variabile membro di clock) – es

 Hello hello = new Hello(); hello.clock.sayTime(); 

i metodi statici non usano alcuna variabile di istanza della class in cui sono definiti. Una buona spiegazione della differenza può essere trovata in questa pagina

Ho sviluppato un interesse per i metodi statici (solo, se ansible) nelle classi “helper”.

La class chiamante non ha bisogno di creare un’altra variabile membro (istanza) della class helper. Basta chiamare i metodi della class helper. Anche la class helper è migliorata perché non hai più bisogno di un costruttore e non hai bisogno di variabili membro (istanza).

Ci sono probabilmente altri vantaggi.

La parola chiave static viene utilizzata per indicare un campo o un metodo come appartenente alla class stessa e non all’istanza. Usando il tuo codice, se l’object Clock è statico, tutte le istanze della class Hello condivideranno questo membro di dati Clock (campo) in comune. Se lo rendi non statico, ogni singola istanza di Hello può avere un campo Clock unico.

Il problema è che hai aggiunto un metodo principale alla tua class Hello modo da poter eseguire il codice. Il problema qui è che il metodo principale è statico e in quanto tale non può riferirsi a campi o metodi non statici al suo interno. Puoi risolvere ciò in due modi:

  1. Rendi statici e tutti i campi e i metodi della class Hello in modo che possano essere indirizzati all’interno del metodo principale . Questa non è una buona cosa da fare (o il motivo sbagliato per rendere un campo e / o un metodo statico)
  2. Crea un’istanza della tua class Hello all’interno del metodo principale e accedi a tutti i suoi campi e metodi nel modo in cui erano destinati in primo luogo.

Per te, questo significa la seguente modifica al tuo codice:

 package hello; public class Hello { private Clock clock = new Clock(); public Clock getClock() { return clock; } public static void main(String args[]) { Hello hello = new Hello(); hello.getClock().sayTime(); } } 

Può anche pensare che i membri statici non abbiano un puntatore “this”. Sono condivisi tra tutte le istanze.

Comprensione dei concetti statici

 public class StaticPractise1 { public static void main(String[] args) { StaticPractise2 staticPractise2 = new StaticPractise2(); staticPractise2.printUddhav(); //true StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */ StaticPractise2.printUddhavsStatic1(); //true staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static things and it organizes in its own heap. So, class static methods, object can't reference */ } } 

Seconda class

 public class StaticPractise2 { public static void printUddhavsStatic1() { System.out.println("Uddhav"); } public void printUddhav() { System.out.println("Uddhav"); } } 

main() è un metodo statico che ha due restrizioni fondamentali:

  1. Il metodo statico non può utilizzare un membro dati non statico o chiamare direttamente un metodo non statico.
  2. this() e super() non possono essere utilizzati nel contesto statico.

     class A { int a = 40; //non static public static void main(String args[]) { System.out.println(a); } } 

Output: errore di compilazione del tempo

Variabili statiche Si può accedere solo con metodi statici, quindi quando dichiariamo le variabili statiche i metodi getter e setter saranno metodi statici

i metodi statici sono un livello di class a cui possiamo accedere usando il nome della class

Di seguito è riportato un esempio per le variabili statiche Getters and Setter:

 public class Static { private static String owner; private static int rent; private String car; public String getCar() { return car; } public void setCar(String car) { this.car = car; } public static int getRent() { return rent; } public static void setRent(int rent) { Static.rent = rent; } public static String getOwner() { return owner; } public static void setOwner(String owner) { Static.owner = owner; } } 

Quando si esegue un progetto, caricare innanzitutto oggetti statici (variabili, metodi, blocchi …).

Quando si esegue questo progetto, caricare prima il metodo principale. Perché è il suo static method . Quindi guarda object "a" object . Ma l’object non è ancora definito. Perché non è statico. Allora vieni come questo errore.