Ho appena trascorso mezz'ora a capire questa cosa, sono riuscito a risolvere il mio codice, ma non capisco completamente cosa sta succedendo e mi chiedevo se qualcuno potesse far luce su di esso.Inizializzazione del campo statico Java
Ho una classe di , che contiene alcuni campi statici (un endpoint di connessione al database, ad esempio) utilizzati da vari altri programmi in base all'attività in corso. Essenzialmente una biblioteca.
Ecco come appariva in precedenza (mentre era ancora rotto);
//DBUtils.java
public final class DBUtils {
private static DBConnection myDBConnection = spawnDBConnection();
private static DBIndex myDBIndex = null;
private static DBConnection spawnDBConnection() {
//connect to the database
//assign a value to myDBIndex (by calling a method on the DBConnection object) <- IMPORTANT
//myDbIndex NOT NULL HERE
System.out.println("database connection completed");
//return the DBConnection object
}
public static searchDB(String name) {
//use the myDBIndex to find a row and return it
}
}
Così brevemente, io sto usando il metodo spawnDBConnection statico() per assegnare un valore ad entrambi myDBConnection e myDBIndex. Funziona perfettamente, la prima linea di uscita dal mio programma è sempre "connessione al database completata", né myDBConnection o myDBIndex sono nulli alla fine del metodo spawnDBConnection(), tutto è come dovrebbe essere.
Il mio programma esterno si presenta così;
//DoSomethingUsefulWithTheDatabase.java
public final class DoSomethingUsefulWithTheDatabase {
public static void main(String args[]) {
DBUtils.searchDB("John Smith"); //fails with NullPointerException on myDBIndex!
}
}
Questa chiamata a searchDB avviene dopo la spawnDBConnection ha finito, ho usato l'uscita standard ampiamente per mostrare questo. Tuttavia, una volta all'interno del metodo searchDB, il valore di myDBIndex è nullo! È un campo statico e non è nullo alla fine di spawnDBConnection, non sono stati effettuati altri assegnamenti e ora è nullo :(
La semplice soluzione era rimuovere "= null" in modo che la dichiarazione del campo ora appaia simili;
private static DBIndex myDBIndex;
Perché che fanno la differenza sto accuratamente confuso da questo
considerare la possibilità di la tua statistica 'finale'. Sarai costretto ad assegnarli esattamente una volta, eliminando questo tipo di sorpresa. –
Questo è un incubo terribile-antipattern quello che stai facendo qui. Accoppia l'inizializzazione della classe per l'acquisizione di una connessione al database. –
Non inizializzare in modo statico DBConnection. Cosa succede se muore myDBConnection, hai intenzione di iniziare a utilizzare DbUtils2 nel tuo codice? –