Domanda

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

  

Impossibile accedere al campo non statico nel metodo statico principale

Quindi ho cambiato la dichiarazione di clock in questo:

static Clock clock = new Clock();

E ha funzionato. Cosa significa mettere quella parola chiave prima della dichiarazione? Che cosa esattamente farà e / o limiterà in termini di cosa si può fare a quell'oggetto?

È stato utile?

Soluzione

I membri

?? statici appartengono alla classe anziché a un'istanza specifica.

Significa che esiste solo un'istanza di un campo statico [1] anche se crei un milione di istanze della classe o tu non crearne nessuno. Sarà condiviso da tutte le istanze.

Poiché anche i metodi statici non appartengono a un'istanza specifica, non possono fare riferimento ai membri dell'istanza. Nell'esempio fornito, main non sa a quale istanza della classe Hello (e quindi a quale istanza della classe Clock ) dovrebbe fare riferimento . I membri statici possono fare riferimento solo ai membri statici . I membri dell'istanza possono ovviamente accedere ai membri statici .

Nota a margine: Naturalmente, i membri statici possono accedere ai membri dell'istanza tramite un riferimento a oggetto .

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 non è questo il punto.

Altri suggerimenti

Significa che esiste solo un'istanza di " clock " in Hello, non uno per ogni istanza separata di " Hello " classe, o più, significa che ci sarà un "orologio" comunemente condiviso riferimento tra tutte le istanze di " Hello " Classe.

Quindi, se dovessi fare un "nuovo Ciao" ovunque nel tuo codice: A- nel primo scenario (prima della modifica, senza usare "statico"), farebbe un nuovo orologio ogni volta che un "nuovo Ciao" si chiama, ma B- nel secondo scenario (dopo la modifica, usando "statico"), ogni "nuovo Ciao" L'istanza continuerebbe a condividere e utilizzare l'iniziale e lo stesso "orologio" riferimento creato per primo.

A meno che tu non abbia bisogno di " clock " da qualche parte al di fuori di main, funzionerebbe altrettanto bene:

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

La parola chiave statica indica che qualcosa (un campo, un metodo o una classe nidificata) è correlato al tipo anziché a qualsiasi particolare istanza di Il tipo. Ad esempio, si chiama Math.sin (...) senza alcuna istanza della classe Math , e in effetti non è possibile creare un'istanza della classe Math .

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


Nota a margine

Java purtroppo consente di accedere ai membri statici come se fossero membri di istanza, ad es.

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

Questo lo rende sembra come se sleep sia un metodo di istanza, ma in realtà è un metodo statico - sempre fa dormire il thread corrente . È buona prassi chiarire questo nel codice chiamante:

// Clearer
Thread.sleep(5000);

La parola chiave statica in Java significa che la variabile o funzione è condivisa tra tutte le istanze di quella classe in quanto appartiene al tipo , non agli oggetti reali stessi.

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

I metodi statici possono essere utilizzati senza istanziare un oggetto.

Utilizzo di base dei 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
}

È così che puoi avere valori condivisi in tutti i membri della classe senza inviare l'istanza della classe Ciao a un'altra classe. E con statico non è necessario creare un'istanza di classe.

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

Puoi semplicemente chiamare valori o metodi statici per nome classe:

Hello.staticValue = "abc";

Statico in Java:

Statico è un modificatore di non accesso. La parola chiave statica appartiene alla classe rispetto all'istanza della classe. può essere utilizzato per collegare una variabile o un metodo a una classe.

La parola chiave statica PU CAN essere utilizzata con:

Metodo

Variabile

Classe nidificata in un'altra classe

Blocco inizializzazione

NON PU be essere utilizzato con:

Classe (non nidificata)

Constructor

Interfacce

Metodo classe interna locale (differenza quindi classe nidificata)

Metodi della classe interna

Variabili di istanza

Variabili locali

Esempio:

Immagina il seguente esempio che ha una variabile di istanza denominata count che è 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();

    }
}

Output:

  

1 1 1

Poiché la variabile di istanza ottiene la memoria al momento della creazione dell'oggetto, ogni oggetto avrà la copia della variabile di istanza, se viene incrementata, non si 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();

    }
}

Output:

  

1 2 3

In questo caso la variabile statica otterrà la memoria una sola volta, se un oggetto cambia il valore della variabile statica, manterrà il suo valore.

Statico con finale:

La variabile globale dichiarata come finale e statica rimane invariata per l'intera esecuzione. Perché, i membri statici vengono archiviati nella memoria della classe e vengono caricati una sola volta nell'intera esecuzione. Sono comuni a tutti gli oggetti della classe. Se dichiari le variabili statiche come finali, nessuno degli oggetti non può cambiare il loro valore in quanto è definitivo. Pertanto, le variabili dichiarate come finali e statiche vengono talvolta chiamate Costanti. Tutti i campi delle interfacce sono indicati come costanti, perché sono finali e statici per impostazione predefinita.

 inserisci qui la descrizione dell'immagine

Risorsa immagine: Final Static

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

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

direttamente, anziché:

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 classe) non è possibile accedere a membri che non sono statici, poiché i loro valori dipendono dall'istanza della classe. Un oggetto Clock non statico, che è un membro di istanza, avrebbe un valore / riferimento diverso per ciascuna istanza della classe Hello e pertanto non è possibile accedervi dalla parte statica della classe.

Finora questa discussione ha ignorato le considerazioni sul classloader. A rigor di termini, i campi statici Java sono condivisi tra tutte le istanze di una classe per un dato classloader .

Per aggiungere risposte esistenti, fammi provare con un'immagine:

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

Un saldo deve essere individuale , quindi non statico.

 inserisci qui la descrizione dell'immagine

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

La parola chiave static viene utilizzata per indicare un campo o un metodo come appartenenti alla classe stessa e non all'istanza. Usando il tuo codice, se l'oggetto Clock è statico, tutte le istanze della classe 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 univoco.

Il problema è che hai aggiunto un metodo principale alla tua classe Hello in modo da poter eseguire il codice. Il problema qui è che il metodo main è statico e come tale non può fare riferimento a campi o metodi non statici al suo interno. Puoi risolverlo in due modi:

  1. Rende statici tutti i campi e i metodi della classe Hello in modo che possano essere indicati all'interno del metodo main . Questa non è davvero una buona cosa da fare (o la ragione sbagliata per rendere statico un campo e / o un metodo)
  2. Crea un'istanza della tua classe 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();
    }
}

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

  

"senza riguardo o relazione con una particolare istanza"

Se pensi a statico in questo modo, diventa più facile comprenderne l'uso nei vari contesti in cui si incontra:

  • Un campo statico è un campo che appartiene alla classe anziché a una particolare istanza

  • Un metodo statico è un metodo che non ha nozione di this ; è definito sulla classe e non conosce alcuna istanza particolare di quella classe a meno che non venga passato un riferimento ad essa

  • Una classe membro statico è una classe nidificata senza alcuna nozione o conoscenza di un'istanza della sua classe inclusa (a meno che non venga passato ad essa un riferimento a un'istanza della classe inclusa)

Statico rende il membro di clock un membro di classe anziché un membro di istanza. Senza la parola chiave statica dovresti creare un'istanza della classe Hello (che ha una variabile membro clock) - ad esempio

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

i metodi statici non usano alcuna variabile di istanza della classe in cui sono definiti. Un'ottima spiegazione della differenza può essere trovata su questa pagina

Ho sviluppato una predilezione per i metodi statici (solo, se possibile) in "helper" classi.

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

Probabilmente ci sono altri vantaggi.

Può anche pensare che i membri statici non abbiano " questo " puntatore. Sono condivisi tra tutti i casi.

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 classe

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

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}
//Here is an example 

public class StaticClass 
{
    static int version;
    public void printVersion() {
         System.out.println(version);
    }
}

public class MainClass 
{
    public static void main(String args[]) {  
        StaticClass staticVar1 = new StaticClass();
        staticVar1.version = 10;
        staticVar1.printVersion() // Output 10

        StaticClass staticVar2 = new StaticClass();
        staticVar2.printVersion() // Output 10
        staticVar2.version = 20;
        staticVar2.printVersion() // Output 20
        staticVar1.printVersion() // Output 20
    }
}

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

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

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

Output: errore tempo di compilazione

Le variabili statiche sono accessibili solo con metodi statici, quindi quando dichiariamo le variabili statiche quei metodi getter e setter saranno metodi statici

i metodi statici è un livello di classe a cui possiamo accedere usando il nome della classe

Il seguente esempio è per le variabili statiche Getter e 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 elementi statici (variabili, metodi, blocchi ...).

Quando si avvia questo metodo principale del progetto, caricare prima. Perché il suo metodo statico . Quindi appare l'oggetto " a " oggetto . Ma l'oggetto non è ancora definito. Perché non è statico. Quindi vieni come questo errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top