国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

論全世界所有程序員都會犯的錯誤

2019-11-17 05:59:15
字體:
來源:轉載
供稿:網友

  當年,某國際巨星的“龍種”曝光,眾人指責他對不起嬌妻,逼得他出面召開記者會,向世人自白他犯了“全世界所有男人都會犯的錯誤”。從來沒犯過這種錯誤的我,也因此經常認為自己不是個男人。

雖然沒犯過“全世界所有男人都會犯的錯誤”,但是我倒是曾經犯了“全世界所有程序員都會犯的錯誤”。不管使用何種語言,全世界所有程序員都一定犯過這種錯誤,那就是:太依靠編譯器,卻不知道編譯器做了哪些事。

  一般來說,越高階的程序語言,會提供越多語法上的便利,以方便程序撰寫,這就俗稱為syntactic sugar,我稱其為“語法上的甜頭”。雖說是甜頭,但是假如你未能了解該語法的實質內涵,很可能會未嘗甜頭,卻吃盡苦頭。

  不久前,我收到一個電子郵件,讀者列出下面的java程序,向我求救??催^這個程序之后,我確定這又是一個“全世界所有程序員都會犯的錯誤”。

程序1

class Singleton
{
PRivate static Singleton
obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance()
{
return obj;
}
}


進入討論組討論。


程序2

public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1); 
System.out.println("obj.counter2=="+obj.counter2);
}
}


  執行結果是:

  obj.counter1==1
  obj.counter2==0

  你有沒有被此結果嚇一跳?乍看程序代碼,你很可能會認為counter1和counter2的值一定 會相等,但執行結果顯然不是如此。其實,程序1被編譯后的程序應該等同于下面的程序3 :

class Singleton
{
private static Singleton obj;
public static int counter1;
public static int counter2;
static
{
// 這就是class constrUCtor
// 在進入此class constructor之前,class已經被JVM
// 配置好內存,所有的static field都會被先設定為0,
// 所以此時counter1和counter2都已經是0,
且singleton為null
obj = new Singleton();
// 問題皆由此行程序產生
// counter1不會在此被設定為0
counter2 = 0;
// counter2再被設定一次0(其實是多此一舉)
}
private Singleton()
{
// 這是instance constructor
counter1++;
counter2++;
}
public static Singleton getInstance()
{
return obj;
}
}


進入討論組討論。

  這是因為:當class具有static field,且直接在宣告處透過“=...”的方式設定其值時,編譯器會自動將這些敘述依序搬到class constructor內。 同樣地,當class具有instance field,且直接在宣告處透過“=...”的方式設定其值時,編譯器會自動將這些敘述依序搬到instance constructor內。

  此程序在class constructor內,還未將static field初始化時(這時候,counter1和counter2都是0),就呼叫instance constructor,而instance constructor竟然還會去更動static field的值,使得counter1和counter2都變成1。

  然后instance constructor執行完,回到class constructor,再把counter2的值設為0(但是counter1維持不變)。最后的結果:counter1等于1,counter2等于0。

  欲改正程序1,方法有三:

  方法一:將singleton field的宣告調到counter1與counter2 field之后。

  這是最好的作法。

  方法二:將counter2=0的宣告中,“=0”的部分刪除。這種作法只有在希望。

  方法三:將初始化的動作搬到class constructors內,自行撰寫,而不依靠編譯器產生。這是最保險的作法。

  如何避免犯下“全世界所有程序員都會犯的錯誤”,我給各位Java程序員的建議是:

  -熟讀Java Language Specification

  -在有疑問時,使用J2SDK所提供的javap來反組譯Java Bytecode,直接觀察編譯后的結果。

進入討論組討論。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泉州市| 宜宾市| 奉化市| 阳新县| 时尚| 达尔| 新昌县| 保德县| 康马县| 黎城县| 奉化市| 兴化市| 南京市| 自治县| 乌兰县| 肃宁县| 玉屏| 叶城县| 宣武区| 同心县| 澄迈县| 普陀区| 昭苏县| 理塘县| 仙居县| 时尚| 盐城市| 黄陵县| 丹阳市| 万宁市| 正宁县| 巴林右旗| 囊谦县| 井陉县| 繁昌县| 克拉玛依市| 澄迈县| 基隆市| 讷河市| 浦北县| 巍山|