Einige Leute haben gefragt: Wie kann der Singleton einen Nullzeiger zurückgeben?
Ich beantworte diese Frage. (Ich kann nicht in einem Kommentar antworten, da ich eine Postleitzahl eingeben muss.)
Zwischen zwei Ereignissen kann null zurückgegeben werden: (1) die Klasse wird geladen und (2) das Objekt dieser Klasse wird erstellt. Hier ist ein Beispiel:
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);
}
}
Lassen Sie uns den Code ausführen:
$ javac A.java
$ java A
x:X@a63599 y:Y@9036e
x:null y:null
Die zweite Zeile zeigt , daß Y.xinstance und X.yinstance ist null ; sie sind null , weil die Variablen X.xinstance ans Y.yinstance gelesen wurden , wenn sie null waren.
Kann das behoben werden? Ja,
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);
}
}
und dieser Code zeigt keine Anomalie:
$ javac A.java
$ java A
x:X@1c059f6 y:Y@152506e
x:X@1c059f6 y:Y@152506e
ABER dies ist keine Option für das Android- Application
Objekt: Der Programmierer steuert nicht die Zeit, zu der es erstellt wird.
Noch einmal: Der Unterschied zwischen dem ersten und dem zweiten Beispiel besteht darin, dass das zweite Beispiel eine Instanz erstellt, wenn der statische Zeiger null ist. Ein Programmierer kann das Android-Anwendungsobjekt jedoch nicht erstellen, bevor sich das System dafür entscheidet.
AKTUALISIEREN
Ein weiteres rätselhaftes Beispiel, in dem sich initialisierte statische Felder befinden 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());
}
}
Und du bekommst:
$ javac Main.java
$ java Main
first: FIRST second: SECOND
first: <FIRST> second: <SECOND>
first: nullFIRSTnull second: nullSECONDnull
Beachten Sie, dass Sie die statische Variablendeklaration nicht um eine Zeile nach oben verschieben können. Der Code wird nicht kompiliert.
<application>
Um dies für andere zu erläutern, die dies implementieren, können Sie den Knoten Ihrer AndroidManifest.xml-Datei so ändern , dass er die folgende Attributdefinition enthält :android:name="MyApp"
. MyApp muss sich unter demselben Paket befinden, auf das Ihr Manifest verweist.