Caricamento classe vs inizializzazione: variabile finale statica Java [duplicato]
Esempio.java
public class Example {
static final int i = 10;
static int j = 20;
static {
System.out.println("Example class loaded and initialized");
}
}
Use.java
import java.util.Scanner;
public class Use {
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
int ch = 1;
while(ch != 0) {
System.out.print("Enter choice: ");
ch = sc.nextInt();
if (ch == 1) {
System.out.println("Example's i = " + Example.i);
} else if(ch == 2){
System.out.println("Example's j = " + Example.j);
}
}
}
}
Quando eseguo con java -verbose:class Use
, e fornisco input, l' 1
output è 10
cioè il i
valore costante . Ma la Example
classe non è ancora stata caricata. Tuttavia, quando fornisco input come 2
, solo allora la Example
classe viene caricata nella JVM, come visibile dall'output dettagliato , quindi viene eseguito il blocco statico all'interno di Example e anche j
il valore di viene inizializzato e quindi stampato.
La mia domanda è: se per l'input, 1
ovvero quando il valore finale statico (costante) di una classe Example
viene richiesto in un'altra classe Use
, da dove viene prelevato il valore costante se la classe Example
non è mai stata caricata nella JVM fino ad allora? Quando e come è stato i
inizializzato il finale statico e archiviato nella memoria JVM?
Risposte
Secondo la sezione 12.4.1 delle specifiche del linguaggio Java (enfasi aggiunta):
Una classe o un'interfaccia di tipo T verrà inizializzata immediatamente prima della prima occorrenza di uno qualsiasi dei 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).
Una variabile costante è una variabile finale inizializzata con un'espressione costante . Nel codice Example.i
è una variabile costante e quindi non causa il caricamento della classe.
Quindi, se la classe non viene caricata, da dove viene il valore com?
La specifica del linguaggio richiede che il compilatore inline il suo valore. Dalla sezione della compatibilità binaria 13.1 :
Un riferimento a un campo che è una variabile costante (§4.12.4) deve essere risolto in fase di compilazione al valore V indicato dall'inizializzatore della variabile costante.
Se tale campo è statico, nessun riferimento al campo dovrebbe essere presente nel codice in un file binario, inclusa la classe o l'interfaccia che ha dichiarato il campo. Tale campo deve sempre sembrare inizializzato (§12.4.2); il valore iniziale di default del campo (se diverso da V) non deve mai essere rispettato.