六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

全世界所有程序員都會(huì)犯的出錯(cuò)

[摘要]當(dāng)年,國際巨星成龍的「龍種」曝光,眾人指責(zé)他對不起嬌妻林鳳嬌,逼得他出面召開記 者會(huì),向世人自白他犯了「全世界所有男人都會(huì)犯的錯(cuò)誤」。從來沒犯過這種錯(cuò)誤的我, 也因此常常認(rèn)為自己不是個(gè)男人。 雖然沒犯過「全世界所有男人都會(huì)犯的錯(cuò)誤」,但是我倒是曾經(jīng)犯了「全世界所有程序員 都會(huì)犯的錯(cuò)誤」。不管使用...
當(dāng)年,國際巨星成龍的「龍種」曝光,眾人指責(zé)他對不起嬌妻林鳳嬌,逼得他出面召開記
者會(huì),向世人自白他犯了「全世界所有男人都會(huì)犯的錯(cuò)誤」。從來沒犯過這種錯(cuò)誤的我,
也因此常常認(rèn)為自己不是個(gè)男人。

雖然沒犯過「全世界所有男人都會(huì)犯的錯(cuò)誤」,但是我倒是曾經(jīng)犯了「全世界所有程序員
都會(huì)犯的錯(cuò)誤」。不管使用何種語言,全世界所有程序員都一定犯過這種錯(cuò)誤,那就是:
太依賴編譯器,卻不知道編譯器做了哪些事。

一般來說,越高階的程序語言,會(huì)提供越多語法上的便利,以方便程序撰寫,這就俗稱為
syntactic sugar,我稱其為「語法上的甜頭」。雖說是甜頭,但是如果你未能了解該語法
的實(shí)質(zhì)內(nèi)涵,很可能會(huì)未嘗甜頭,卻吃盡苦頭。

不久前,我收到一個(gè)電子郵件,讀者列出下面的Java程序,向我求救。看過這個(gè)程序之后
,我確定這又是一個(gè)「全世界所有程序員都會(huì)犯的錯(cuò)誤」。

// 程序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); } }

執(zhí)行結(jié)果是:
obj.counter1==1
obj.counter2==0

你有沒有被此結(jié)果嚇一跳?乍看程序代碼,你很可能會(huì)認(rèn)為counter1和counter2的值一定
會(huì)相等,但執(zhí)行結(jié)果顯然不是如此。其實(shí),程序1被編譯后的程序應(yīng)該等同于下面的程序3


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

這是因?yàn)椋寒?dāng)class具有static field,且直接在宣告處透過「=...」的方式設(shè)定其值時(shí),
編譯器會(huì)自動(dòng)將這些敘述依序搬到class constructor內(nèi)。同樣地,當(dāng)class具有instance
field,且直接在宣告處透過「=...」的方式設(shè)定其值時(shí),編譯器會(huì)自動(dòng)將這些敘述依序
搬到instance constructor內(nèi)。

此程序在class constructor內(nèi),還未將static field初始化時(shí)(這時(shí)候,counter1和cou
nter2都是0),就呼叫instance constructor,而instance constructor竟然還會(huì)去更動(dòng)
static field的值,使得counter1和counter2都變成1。然后instance constructor執(zhí)行完
,回到class constructor,再把counter2的值設(shè)為0(但是
counter1維持不變)。最后的結(jié)果:counter1等于1,counter2等于0。

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

-方法一:將singleton field的宣告調(diào)到counter1與counter2 field之后。
這是最好的作法。
-方法二:將counter2=0的宣告中,「=0」的部分刪除。這種作法只有在希望
-方法三:將初始化的動(dòng)作搬到class constructors內(nèi),自行撰寫,而不依賴
編譯器產(chǎn)生。這是最保險(xiǎn)的作法。

如何避免犯下「全世界所有程序員都會(huì)犯的錯(cuò)誤」,我給各位Java程序員
的建議是:
-熟讀Java Language Specification
-在有疑問時(shí),使用J2SDK所提供的javap來反組譯Java Bytecode,直接觀察
編譯后的結(jié)果。

下面是我用javap來反組譯程序1的示范:

C:\>javap -c -classpath . Singleton Compiled from MyMain.java class Singleton extends java.lang.Object { public static int counter1; public static int counter2; public static Singleton getInstance(); static {}; } Method Singleton() 0 aload_0 1 invokespecial #1 <Method java.lang.Object()> 4 getstatic #2 <Field int counter1> 7 iconst_1 8 iadd 9 putstatic #2 <Field int counter1> 12 getstatic #3 <Field int counter2> 15 iconst_1 16 iadd 17 putstatic #3 <Field int counter2> 20 return Method Singleton getInstance() 0 getstatic #4 <Field Singleton obj> 3 areturn Method static {} 0 new #5 <Class Singleton> 3 dup 4 invokespecial #6 <Method Singleton()> 7 putstatic #4 <Field Singleton obj> 10 iconst_0 11 putstatic #3 <Field int counter2> 14 return

其實(shí)Java的syntactic sugar并不算多,C#的syntactic sugar才真的是無所不在,
也因此C#的初學(xué)者更容易犯了「全世界所有程序員都會(huì)犯的錯(cuò)誤」。許多C#的書都會(huì)一邊
介紹C#語法,一邊介紹編譯之后MSIL(.NET的中間語言,類似Java的Bytecode)的結(jié)果,
然而Java的書卻鮮少這么做。

雖說是「全世界所有程序員都會(huì)犯的錯(cuò)誤」,但是這不代表你犯了此錯(cuò)誤之后,仍可以同
愛借錢的曹啟泰一般地「抬頭挺胸、理直氣壯」。只要有心,其實(shí)這一類的錯(cuò)誤仍是可以
避免的。





主站蜘蛛池模板: 日本中字 | 永久免费mv网站入口 | 天堂伦理| 三级小说在线 | 日韩经典在线 | 亚洲 欧美 日韩 综合 | 天天做天天爽爽快快 | 丝袜 欧美 视频 首页 在线 | 日本一区二区三区免费观看 | 伊人婷婷色香五月综合缴激情 | 欧美一级在线观看视频 | 午夜免费啪视频 | 四虎影院精品在线观看 | 先锋影音亚洲 | 日日噜噜噜夜夜爽爽狠狠视频 | 在线看欧美日韩中文字幕 | 桃花视频在线观看免费迅雷 | 欧美又肥又胖的大bbwⅹ | 日本久久伊人 | 午夜免费啪视频 | 亚洲人成网男女大片在线播放 | 一级做a爰片性色毛片思念网 | 在线资源站 | 午夜影视免费观看 | 亚洲爱爱网 | 亚洲欧洲eeea在线观看 | 三级黄色片免费 | 日本精品在线播放 | 欧美一级淫片aaaaaaa视频 | 伊人成人在线观看 | 日日夜夜伊人 | 青苹果a4yy私人毛片 | 日本综合欧美一区二区三区 | 任我鲁这里有精品视频在线播 | 最新国产精品亚洲 | 欧美丝袜一区二区三区 | 日本高清不卡免费 | 午夜欧美福利 | 一二三四影视大全免费观看电视剧 | 四虎新地址 | 欧美性猛交一区二区三区 |