posts - 8,  comments - 6,  trackbacks - 0

          1.10  “==”不等于“.equals”

          這里舉出一個Java編程程序員經常碰到的問題。例如現在是凌晨3點,在你喝完第4杯咖啡后,你設法找到正確的邏輯來解決復雜的編程問題。到目前,你幾乎不能思考String和Object引用,因為你已經昏昏欲睡了。然后糟糕的事情發生了……不,并不是Java溢出,而是如下所示。

          String name = getName();
          if (name == "Sleepy") // oops!
          {
          doSomething();
          }

          你快速編譯并測試代碼后,代碼似乎正常運行。終于到下班回家休息的時候了!然而,一段時間后,應用程序測試發現了一個間歇性錯誤,并跟蹤到此錯誤的來源恰好是這段代碼。

          “怎么會這樣?”你可能會憤怒地說,“前幾天我還試驗過類似的String比較,并且能夠正確運行!”。但是,你需要首先重溫一下Java對象引用的概念。一個對象變量是一個指向存儲在堆內存(heap memory)中實際對象的引用(指針)。當為另一個變量分配一個變量時,事實上分配的是引用而不是實際的對象(如圖1-1所示):

          String a, b, c, d;
          a = "123";
          b = a;
          c = new String("123");
          d = "WCJ";

          圖 1-1  對象引用

          Java中,“==”運算符用來比較兩個引用以查看它們是否指向同一個內存對象。而對于String實例,運行時狀態會盡可能地確保任意兩個具有相同字符信息的String字面值指向同一個內部對象。此過程稱為駐留(interning),但是它并不有助于每個String的比較。一個原因是垃圾收集器線程刪除了駐留值,另一個原因是String所在的位置可能被一個由String構造函數創建的新實例占用。如果是這樣,“==”將總是返回false。
          可以設計equals方法來比較兩個對象的狀態(state)或每個對象的內容。對你自己的類,必須重寫此方法來使它正確操作。但是如果使用equals方法,String實例總是能夠正確地比較。假定所有的String值是駐留的,下面的代碼段說明了此問題:

          String name1, name2, name3;
          name1 = "123";

          name2 = name1;
          if (name1 == name2) {}         // true
          if (name1.equals(name2)) {}    // true

          name2 = "123";
          if (name1 == name2) {}         // usually true
          if (name1.equals(name2)) {}    // true

          name3 = new String("123");
          if (name1 == name3) {}         // false
          if (name1.equals(name3)) {}    // true


          注意:

          總是使用.equals來比較兩個String值,盡管使用“==”運算符看似能夠正確操作。對于大多數應用程序而言,即使它能正確運行,但“==”代碼事實上是錯誤的,而只有equals是正確的。因此告訴所有你的開發同行支持String的“equals(平等)”權吧(這很可能是本書中最差的雙關語)!


          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          主站蜘蛛池模板: 华安县| 尚志市| 西平县| 宜良县| 南丹县| 于田县| 绥棱县| 台北市| 高碑店市| 华容县| 九龙城区| 科技| 佳木斯市| 安徽省| 锡林郭勒盟| 岚皋县| 旅游| 剑阁县| 分宜县| 武夷山市| 迁西县| 通城县| 汾阳市| 黑河市| 河池市| 通辽市| 蕲春县| 武清区| 将乐县| 隆子县| 南靖县| 白玉县| 徐汇区| 浦县| 莎车县| 新绛县| 介休市| 岢岚县| 通辽市| 星座| 西乌|