method - static class java




Valore della variabile statica non modificato anche dopo l'inizializzazione della classe figlio in Java (6)

Come altri citano, il blocco statico non viene eseguito perché la classe non è inizializzata come prima .

Si noti che i nomi delle convenzioni di classe iniziano con una lettera maiuscola.

Un esempio più chiaro per mostrare la classe Overriding non viene utilizzato:

class Par {
    static int y = 4;
    public static void main(String args[]) {
        System.out.println(Checks.y);    // Here printing 4
        System.out.println(new Checks().y);    // Here printing 5
    }
}

class Checks extends Par {
   static {
        y = 5;
    }
}

Questa domanda ha già una risposta qui:

Quando invoco la variabile statica y usando Checks.y ( Checks è una sottoclasse), il blocco statico non viene eseguito e il valore di y non viene aggiornato.

class Par {
    static int y = 4;
}

class Checks extends Par {
    static {
        y = 5;
    }
}

public class Check {
    public static void main(String args[]) {
        System.out.println(Checks.y); // here printing 4
    }
}

Poiché la static è condivisa tra tutte le sottoclassi, il valore dovrebbe essere aggiornato.

Quale potrebbe essere la ragione dietro di esso?


Come per il tuo esempio, il blocco statico della classe Check non viene mai chiamato. I blocchi statici vengono sempre eseguiti prima della creazione dell'oggetto. Se aggiungi controlli, object = new checks() , nella tua classe Check dovresti vedere il valore atteso.


Ecco una variante di come si forza l'inizializzazione della classe Checks .

class Par {
    static int y = 4;
}

class Checks extends Par {
    public static int x;
    static {
        y = 5;
    }
}

 class Check {
    public static void main(String args[]) {
        System.out.println(checks.y); // Prints 4
        System.out.println(checks.x); // Prints 0
        System.out.println(checks.y); // Prints 5
    }
}

Il campo y non è dichiarato dai Checks classe.

La lettura dei campi statici non innesca l'inizializzazione della classe di riferimento ( Checks ), a meno che quella classe sia quella in cui è dichiarato il campo (vedere la citazione JLS di seguito). In questo esempio, anche se si accede a y tramite Checks , verrà attivata solo l'inizializzazione di Par perché Par è la classe che dichiara y .

In altre parole, la classe Checks è in un certo senso utilizzata in fase di runtime.

Questo è forse un esempio del perché è sbagliato accedere ai membri static attraverso sottoclassi, qualcosa che causa un avviso in fase di compilazione.

C'è una spiegazione semplice nelle specifiche :

12.4.1. Quando si verifica l'inizializzazione

Una classe o un tipo di interfaccia T verrà inizializzato immediatamente prima della prima occorrenza di una delle seguenti operazioni:

  • T è una classe e viene creata un'istanza di T.

  • Viene invocato un metodo statico dichiarato da T.

  • Viene assegnato un campo statico dichiarato da T.

  • Viene utilizzato un campo statico dichiarato da T e il campo non è una variabile costante (§4.12.4).

  • T è una classe di livello superiore (§7.6) e viene eseguita un'istruzione di asserzione (§14.10) nidificata lessicalmente in T (§8.1.3).
    ...
    Un riferimento a un campo statico (§8.3.1.1) causa l'inizializzazione solo della classe o dell'interfaccia che in realtà lo dichiara, anche se potrebbe essere riferito tramite il nome di una sottoclasse, una sottointerfaccia o una classe che implementa un'interfaccia.

L'ultima nota spiega perché la sottoclasse non viene inizializzata.


Questo perché il blocco static nella classe di checks non viene eseguito. Sebbene si menzioni la classe, la JVM non la carica affatto.

Puoi confermare questo aggiungendo un altro System.out.println all'interno del blocco statico.

class checks extends par {

    static {
        System.out.println("Test");
        y = 5;
    }
}

La parola Test non verrà mai stampata.

Leggi la sezione 12.4.1. Quando l'inizializzazione si verifica nella specifica del linguaggio Java per saperne di più.


Qui:

System.out.println(checks.y); // Here printing 4

y riferisce a un campo della classe par . Questo accesso al campo si traduce nel caricamento della classe par (la classe genitore) in base al JLS (l'enfasi è mia):

12.4. Inizializzazione di classi e interfacce

....

12.4.1. Quando si verifica l'inizializzazione

Una classe o un tipo di interfaccia T verrà inizializzato immediatamente prima della prima occorrenza di una delle seguenti: T è una classe e viene creata un'istanza di T. Viene invocato un metodo statico dichiarato da T.

Viene assegnato un campo statico dichiarato da T.

Viene utilizzato un campo statico dichiarato da T e il campo non è una variabile costante (§4.12.4).

T è una classe di livello superiore (§7.6) e viene eseguita un'istruzione di asserzione (§14.10) nidificata lessicalmente in T (§8.1.3).

Ma non carica la classe di checks perché (l'enfasi è mia):

Un riferimento a un campo statico (§8.3.1.1) causa l'inizializzazione solo della classe o dell'interfaccia che in realtà lo dichiara , anche se potrebbe essere riferito tramite il nome di una sottoclasse, una sottointerfaccia o una classe che implementa un'interfaccia.





static-block