java 81 08,Java更多的库谜题81:烧焦到无法识别
下面這個(gè)程序看起來(lái)是在用一種特殊的方法做一件普通的事。那么,它會(huì)打印出什么呢?
public class Greeter{
public static void main(String[] args){
String greeting = "Hello World";
for(int i = 0; i < greeting.length(); i++)
System.out.write(greeting.charAt(i));
}
}
盡管這個(gè)程序有點(diǎn)奇怪,但是我們沒有理由懷疑它會(huì)產(chǎn)生不正確的行為。它將“Hello World”寫入了System.out,每次寫一個(gè)字符。你可能會(huì)意識(shí)到write方法只會(huì)使用其輸入?yún)?shù)的低位字節(jié)(lower-order byte)。所以當(dāng)“Hello World”含有任何外來(lái)字符的時(shí)候,可能會(huì)造成一些麻煩,但這里不會(huì):因?yàn)椤癏ello World”完全是由ASCII字符組成的。無(wú)論你是每次打印一個(gè)字符,還是一次全部打印,結(jié)果都應(yīng)該是一樣的:這個(gè)程序應(yīng)該打印Hello World。然而,如果你運(yùn)行該程序,就會(huì)發(fā)現(xiàn)它不會(huì)打印任何東西。那句問候語(yǔ)到哪里去了?難道是程序認(rèn)為它并不令人愉快?
這里的問題在于System.out是帶有緩沖的。Hello World中的字符被寫入了System.out的緩沖區(qū),但是緩沖區(qū)從來(lái)都沒有被刷新(flush)。大多數(shù)的程序員認(rèn)為,當(dāng)有輸出產(chǎn)生的時(shí)候System.out和System.err會(huì)自動(dòng)地進(jìn)行刷新,這并不完全正確。這2個(gè)流都屬于PrintStream類型,在5.0版[Java-API]中,有關(guān)這個(gè)類型的文檔敘述道:
一個(gè)PrintStream可以被創(chuàng)建為自動(dòng)刷新的;這意味著當(dāng)一個(gè)字節(jié)數(shù)組(byte array)被寫入,或者某個(gè)println方法被調(diào)用,或者一個(gè)換行字符或字節(jié)(‘\n’)被寫入之后,PrintStream類型的flush方法就會(huì)被自動(dòng)地調(diào)用。
System.out和System.err所引用的流確實(shí)是PrintStream的能夠自動(dòng)刷新的變體,但是上面的文檔中并沒有提及write(int)方法。有關(guān)write(int)方法的文檔敘述道:將指定的byte寫入流。如果這個(gè)byte是一個(gè)換行字符,并且流可以自動(dòng)刷新,那么flush方法將被調(diào)用[Java-API]。實(shí)際上,write(int)是一個(gè)在自動(dòng)刷新(automatic flushing)功能開啟的情況下不刷新PrintStream的輸出方法(output method)。
令人好奇的是,如果這個(gè)程序改用print(char)去替代write(int),它就會(huì)刷新System.out并打印出Hello World。這種行為與print(char)的文檔是矛盾的,因?yàn)槠湮臋n敘述道[Java-API]:
打印一個(gè)字符:這個(gè)字符將根據(jù)平臺(tái)缺省的字符編碼方式被翻譯成為一個(gè)或多個(gè)字節(jié),并且這些字節(jié)將完全按照write(int)方法的方式被寫出。
類似地,如果程序改用print(String),它也會(huì)對(duì)流進(jìn)行刷新,雖然文檔中是禁止這么做的。相應(yīng)的文檔確實(shí)應(yīng)該被修改為描述該方法的實(shí)際行為,而修改方法的行為則會(huì)破壞穩(wěn)定性。
修改這個(gè)程序最簡(jiǎn)單的方法就是在循環(huán)之后加上一個(gè)對(duì)System.out.flush方法的調(diào)用。經(jīng)過(guò)這樣的修改之后,程序就會(huì)正常地打印出Hello World。當(dāng)然,更好的辦法是重寫這個(gè)程序,使用我們更熟悉的System.out.println方法在控制臺(tái)上產(chǎn)生輸出。
這個(gè)謎題的教訓(xùn)與謎題23一樣:盡可能使用熟悉的慣用法;如果你不得不使用陌生的API,請(qǐng)一定要參考相關(guān)的文檔。這里有3條教訓(xùn)給API的設(shè)計(jì)者們:請(qǐng)讓你們的方法的行為能夠清晰的反映在方法名上;請(qǐng)清楚而詳細(xì)地給出這些行為的文檔;請(qǐng)正確地實(shí)現(xiàn)這些行為。
Java更多的庫(kù)謎題81:燒焦到無(wú)法識(shí)別.doc
下載Word文檔到電腦,方便收藏和打印[全文共1322字]
編輯推薦:
下載Word文檔
總結(jié)
以上是生活随笔為你收集整理的java 81 08,Java更多的库谜题81:烧焦到无法识别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gramer法则matlab,东南大学几
- 下一篇: 秋田犬多少钱?秋田犬价格游戏攻略