亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        JAVA字符謎題3:畜牧場(chǎng)

        字號(hào):

        George Orwell的《畜牧場(chǎng)(Animal Farm)》一書的讀者可能還記得老上校的宣言:“所有的動(dòng)物都是平等的?!毕旅娴腏ava程序試圖要測(cè)試這項(xiàng)宣言。那么,它將打印出什么呢?
            public class AnimalFarm{
             public static void main(String[] args){
             final String pig = "length: 10";
             final String dog = "length: " + pig.length();
             System.out. println("Animals are equal: "
             + pig == dog);
             }
            }
             對(duì)該程序的表面分析可能會(huì)認(rèn)為它應(yīng)該打印出Animal are equal: true。畢竟,pig和dog都是final的string類型變量,它們都被初始化為字符序列“l(fā)ength: 10”。換句話說,被pig和dog引用的字符串是且永遠(yuǎn)是彼此相等的。然而,==操作符測(cè)試的是這兩個(gè)對(duì)象引用是否正好引用到了相同的對(duì)象上。在本例中,它們并非引用到了相同的對(duì)象上。
            你可能知道String類型的編譯期常量是內(nèi)存限定的。換句話說,任何兩個(gè)String類型的常量表達(dá)式,如果標(biāo)明的是相同的字符序列,那么它們就用相同的對(duì)象引用來表示。如果用常量表達(dá)式來初始化pig和dog,那么它們確實(shí)會(huì)指向相同的對(duì)象,但是dog并不是用常量表達(dá)式初始化的。既然語言已經(jīng)對(duì)在常量表達(dá)式中允許出現(xiàn)的操作作出了限制,而方法調(diào)用又不在其中,那么,這個(gè)程序就應(yīng)該打印Animal are equal: false,對(duì)嗎?
            嗯,實(shí)際上不對(duì)。如果你運(yùn)行該程序,你就會(huì)發(fā)現(xiàn)它打印的只是false,并沒有其它的任何東西。它沒有打印Animal are equal: 。它怎么會(huì)不打印這個(gè)字符串字面常量呢?畢竟打印它才是正確的呀!謎題11的解謎方案包含了一條暗示:+ 操作符,不論是用作加法還是字符串連接操作,它都比 == 操作符的優(yōu)先級(jí)高。因此,println方法的參數(shù)是按照下面的方式計(jì)算的:
            System.out.println(("Animals are equal: " + pig) == dog);
             這個(gè)布爾表達(dá)式的值當(dāng)然是false,它正是該程序的所打印的輸出。
            有一個(gè)肯定能夠避免此類窘境的方法:在使用字符串連接操作符時(shí),總是將非平凡的操作數(shù)用括號(hào)括起來。更一般地講,當(dāng)你不能確定你是否需要括號(hào)時(shí),應(yīng)該選擇穩(wěn)妥地做法,將它們括起來。如果你在println語句中像下面這樣把比較部分括起來,它將產(chǎn)生所期望的輸出Animals are equal: false :
            System.out.println("Animals are equal: " + (pig == dog));
             可以論證,該程序仍然有問題。
            如果可以的話,你的代碼不應(yīng)該依賴于字符串常量的內(nèi)存限定機(jī)制。內(nèi)存限定機(jī)制只是設(shè)計(jì)用來減少虛擬機(jī)內(nèi)存占有量的,它并不是作為程序員可以使用的一種工具而設(shè)計(jì)的。就像這個(gè)謎題所展示的,哪一個(gè)表達(dá)式會(huì)產(chǎn)生字符串常量并非總是很顯而易見。
            更糟的是,如果你的代碼依賴于內(nèi)存限定機(jī)制實(shí)現(xiàn)操作的正確性,那么你就必須仔細(xì)地了解哪些域和參數(shù)必定是內(nèi)存限定的。編譯器不會(huì)幫你去檢查這些不變量,因?yàn)閮?nèi)存限定的和不限定的字符串使用相同的類型(String)來表示的。這些因在內(nèi)存中限定字符串失敗而導(dǎo)致的bug是非常難以探測(cè)到的。
            在比較對(duì)象引用時(shí),你應(yīng)該優(yōu)先使用equals方法而不是 == 操作符,除非你需要比較的是對(duì)象的標(biāo)識(shí)而不是對(duì)象的值。通過把這個(gè)教訓(xùn)應(yīng)用到我們的程序中,我們給出了下面的println語句,這才是它應(yīng)該具有的模樣。很明顯,在用這種方式訂正了該程序之后,它將打印出true:
            System.out.println("Animals are equal: " + pig.equals(dog));
             這個(gè)謎題對(duì)語言設(shè)計(jì)者來說有兩個(gè)教訓(xùn)。
            字符串連接的優(yōu)先級(jí)不應(yīng)該和加法一樣。這意味著重載 + 操作符來執(zhí)行字符串連接是有問題的,就像在謎題11中提到的一樣。
            還有就是,對(duì)于不可修改的類型,例如String,其引用的等價(jià)性比值的等價(jià)性更加讓人感到迷惑。也許 == 操作符在被應(yīng)用于不可修改的類型時(shí)應(yīng)該執(zhí)行值比較。要實(shí)現(xiàn)這一點(diǎn),一種方法是將 == 操作符作為equals方法的簡(jiǎn)便寫法,并提供一個(gè)單獨(dú)的類似于System.identityHashCode的方法來執(zhí)行引用標(biāo)識(shí)的比較。