บางคนถามว่า: ซิงเกิลสามารถกลับตัวชี้โมฆะได้อย่างไร
ฉันกำลังตอบคำถามนั้น (ฉันไม่สามารถตอบในความคิดเห็นเพราะฉันต้องโพสต์รหัส)
มันอาจกลับมาเป็นโมฆะในระหว่างสองเหตุการณ์: (1) โหลดคลาสและ (2) วัตถุของคลาสนี้ถูกสร้างขึ้น นี่คือตัวอย่าง:
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);
}
}
ลองเรียกใช้รหัส:
$ javac A.java
$ java A
x:X@a63599 y:Y@9036e
x:null y:null
ที่สองแสดงให้เห็นว่าเส้นY.xinstanceและX.yinstanceเป็นnull ; พวกเขาเป็นโมฆะเพราะตัวแปรX.xinstanceและY.yinstanceถูกอ่านเมื่อพวกเขาเป็นโมฆะ
สามารถแก้ไขได้หรือไม่ ใช่,
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);
}
}
และรหัสนี้ไม่แสดงความผิดปกติ:
$ javac A.java
$ java A
x:X@1c059f6 y:Y@152506e
x:X@1c059f6 y:Y@152506e
แต่นี่ไม่ใช่ตัวเลือกสำหรับApplication
วัตถุAndroid : โปรแกรมเมอร์ไม่ได้ควบคุมเวลาเมื่อมันถูกสร้างขึ้น
อีกครั้ง: ความแตกต่างระหว่างตัวอย่างแรกและตัวอย่างที่สองคือตัวอย่างที่สองสร้างอินสแตนซ์ถ้าตัวชี้คงที่เป็นโมฆะ แต่โปรแกรมเมอร์ไม่สามารถสร้างวัตถุประยุกต์ใช้ Android ก่อนที่ระบบจะตัดสินใจที่จะทำมัน
UPDATE
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());
}
}
และคุณจะได้รับ:
$ javac Main.java
$ java Main
first: FIRST second: SECOND
first: <FIRST> second: <SECOND>
first: nullFIRSTnull second: nullSECONDnull
โปรดทราบว่าคุณไม่สามารถย้ายการประกาศตัวแปรแบบคงที่หนึ่งบรรทัดบนโค้ดจะไม่คอมไพล์
<application>
โหนดของไฟล์ AndroidManifest.xmlandroid:name="MyApp"
ของคุณให้มีความหมายแอตทริบิวต์ต่อไปนี้: MyApp จะต้องอยู่ภายใต้แพคเกจเดียวกันกับที่อ้างอิงของคุณ