JAVA字符謎題5:令人暈頭轉(zhuǎn)向的Hello

字號:

下面的程序是對一個老生常談的例子做出了稍許的變化之后的版本。那么,它會打印出什么呢?
    /**
     * Generated by the IBM IDL-to-Java compiler, version 1.0
     * from F:\TestRoot\apps\a1\units\include\PolicyHome.idl
     * Wednesday, June 17, 1998 6:44:40 o’clock AM GMT+00:00
     */
    public class Test{
     public static void main(String[] args){
     System.out.print("Hell");
     System.out.println("o world");
     }
    }
     這個謎題看起來相當(dāng)簡單。該程序包含了兩條語句,第一條打印Hell,而第二條在同一行打印o world,從而將兩個字符串有效地連接在了一起。因此,你可能期望該程序打印出Hello world。但是很可惜,你犯了錯,實(shí)際上,它根本就通不過編譯。
    問題在于注釋的第三行,它包含了字符\units。這些字符以反斜杠(\)以及緊跟著的字母u開頭的,而它(\u)表示的是一個Unicode轉(zhuǎn)義字符的開始。遺憾的是,這些字符后面沒有緊跟四個十六進(jìn)制的數(shù)字,因此,這個Unicode轉(zhuǎn)義字符是病構(gòu)的,而編譯器則被要求拒絕該程序。Unicode轉(zhuǎn)義字符必須是良構(gòu)的,即使是出現(xiàn)在注釋中也是如此。
    在注釋中插入一個良構(gòu)的Unicode轉(zhuǎn)義字符是合法的,但是我們幾乎沒有什么理由去這么做。程序員有時(shí)會在JavaDoc注釋中使用Unicode轉(zhuǎn)義字符來在文檔中生成特殊的字符。
    // Unicode轉(zhuǎn)義字符在JavaDoc注釋中有問題的用法
    /**
     * This method calls itself recursively, causing a
     * StackOverflowError to be thrown.
     * The algorithm is due to Peter von der Ah\u00E9.
     */
    這項(xiàng)技術(shù)表示了Unicode轉(zhuǎn)義字符的一種沒什么用處的用法。在Javadoc注釋中,應(yīng)該使用HTML實(shí)體轉(zhuǎn)義字符來代替Unicode轉(zhuǎn)義字符:
    /**
     * This method calls itself recursively, causing a
     * StackOverflowError to be thrown.
     * The algorithm is due to Peter von der Ahé.
     */
     前面的兩個注釋都應(yīng)該是的在文檔中出現(xiàn)的名字為“Peter der Ahé”,但是后一個注釋在源文件中還是可理解的。
    可能你會感到很詫異,在這個謎題中,問題出在注釋這一信息來源自一個實(shí)際的bug報(bào)告。該程序是機(jī)器生成的,這使得我們很難追蹤到問題的源頭——IDL-to-Java編譯器。為了避免讓其他程序員也陷入此境地,在沒有將Windows文件名進(jìn)行預(yù)先處理,以消除的其中的反斜杠的情況下,工具應(yīng)該確保不將Windows文件名置于所生成的Java源文件的注釋中。
    總之,要確保字符\u不出現(xiàn)在一個合法的Unicode轉(zhuǎn)義字符上下文之外,即使是在注釋中也是如此。在機(jī)器生成的代碼中要特別注意此問題。