Certaines personnes ont demandé: comment le singleton peut-il renvoyer un pointeur nul?
Je réponds à cette question. (Je ne peux pas répondre dans un commentaire car j'ai besoin de poster du code.)
Il peut retourner null entre deux événements: (1) la classe est chargée et (2) l'objet de cette classe est créé. Voici un exemple:
class X {
static X xinstance;
static Y yinstance = Y.yinstance;
X() {xinstance=this;}
}
class Y {
static X xinstance = X.xinstance;
static Y yinstance;
Y() {yinstance=this;}
}
public class A {
public static void main(String[] p) {
X x = new X();
Y y = new Y();
System.out.println("x:"+X.xinstance+" y:"+Y.yinstance);
System.out.println("x:"+Y.xinstance+" y:"+X.yinstance);
}
}
Exécutons le code:
$ javac A.java
$ java A
x:X@a63599 y:Y@9036e
x:null y:null
La deuxième ligne montre que Y.xinstance et X.yinstance sont nuls ; ils sont nuls car les variables X.xinstance et Y.yinstance ont été lues quand elles étaient nulles.
Cela peut-il être corrigé? Oui,
class X {
static Y y = Y.getInstance();
static X theinstance;
static X getInstance() {if(theinstance==null) {theinstance = new X();} return theinstance;}
}
class Y {
static X x = X.getInstance();
static Y theinstance;
static Y getInstance() {if(theinstance==null) {theinstance = new Y();} return theinstance;}
}
public class A {
public static void main(String[] p) {
System.out.println("x:"+X.getInstance()+" y:"+Y.getInstance());
System.out.println("x:"+Y.x+" y:"+X.y);
}
}
et ce code ne montre aucune anomalie:
$ javac A.java
$ java A
x:X@1c059f6 y:Y@152506e
x:X@1c059f6 y:Y@152506e
MAIS ce n'est pas une option pour l' Application
objet Android : le programmeur ne contrôle pas l'heure de sa création.
Encore une fois: la différence entre le premier exemple et le second est que le deuxième exemple crée une instance si le pointeur statique est nul. Mais un programmeur ne peut pas créer l' objet d'application Android avant que le système ne décide de le faire.
MISE À JOUR
Un autre exemple déroutant où se trouvent des champs statiques initialisés null
.
Main.java :
enum MyEnum {
FIRST,SECOND;
private static String prefix="<", suffix=">";
String myName;
MyEnum() {
myName = makeMyName();
}
String makeMyName() {
return prefix + name() + suffix;
}
String getMyName() {
return myName;
}
}
public class Main {
public static void main(String args[]) {
System.out.println("first: "+MyEnum.FIRST+" second: "+MyEnum.SECOND);
System.out.println("first: "+MyEnum.FIRST.makeMyName()+" second: "+MyEnum.SECOND.makeMyName());
System.out.println("first: "+MyEnum.FIRST.getMyName()+" second: "+MyEnum.SECOND.getMyName());
}
}
Et vous obtenez:
$ javac Main.java
$ java Main
first: FIRST second: SECOND
first: <FIRST> second: <SECOND>
first: nullFIRSTnull second: nullSECONDnull
Notez que vous ne pouvez pas déplacer la déclaration de variable statique d'une ligne vers le haut, le code ne sera pas compilé.
<application>
nœud de votre fichier AndroidManifest.xml pour inclure la définition d'attribut suivant:android:name="MyApp"
. MyApp doit se trouver sous le même package que vos références de manifeste.