国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

equals()

2019-11-11 00:47:16
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

 equals()

       超類(lèi)Object中有這個(gè)equals()方法,該方法主要用于比較兩個(gè)對(duì)象是否相等。該方法的源碼如下:

[java] view plain copy 在CODE上查看代碼片public boolean equals(Object obj) {      return (this == obj);      }  

       我們知道所有的對(duì)象都擁有標(biāo)識(shí)(內(nèi)存地址)和狀態(tài)(數(shù)據(jù)),同時(shí)“==”比較兩個(gè)對(duì)象的的內(nèi)存地址,所以說(shuō)使用Object的equals()方法是比較兩個(gè)對(duì)象的內(nèi)存地址是否相等,即若object1.equals(object2)為true,則表示equals1和equals2實(shí)際上是引用同一個(gè)對(duì)象。雖然有時(shí)候Object的equals()方法可以滿(mǎn)足我們一些基本的要求,但是我們必須要清楚我們很大部分時(shí)間都是進(jìn)行兩個(gè)對(duì)象的比較,這個(gè)時(shí)候Object的equals()方法就不可以了,實(shí)際上JDk中,String、Math等封裝類(lèi)都對(duì)equals()方法進(jìn)行了重寫(xiě)。下面是String的equals()方法:

[java] view%20plain copy public boolean equals(Object anObject) {      if (this == anObject) {          return true;      }      if (anObject instanceof String) {          String anotherString = (String)anObject;          int n = count;          if (n == anotherString.count) {          char v1[] = value;          char v2[] = anotherString.value;          int i = offset;          int j = anotherString.offset;          while (n-- != 0) {              if (v1[i++] != v2[j++])              return false;          }          return true;          }      }      return false;      }  

       對(duì)于這個(gè)代碼段:if%20(v1[i++]%20!=%20v2[j++])return%20false;我們可以非常清晰的看到String的equals()方法是進(jìn)行內(nèi)容比較,而不是引用比較。至于其他的封裝類(lèi)都差不多。

       在Java規(guī)范中,它對(duì)equals()方法的使用必須要遵循如下幾個(gè)規(guī)則:

       equals%20方法在非空對(duì)象引用上實(shí)現(xiàn)相等關(guān)系:

      1、自反性:對(duì)于任何非空引用值%20x,x.equals(x)%20都應(yīng)返回%20true。

      2、對(duì)稱(chēng)性:對(duì)于任何非空引用值%20x%20和%20y,當(dāng)且僅當(dāng)%20y.equals(x)%20返回%20true%20時(shí),x.equals(y)%20才應(yīng)返回%20true。

      3、傳遞性:對(duì)于任何非空引用值%20x、y%20和%20z,如果%20x.equals(y)%20返回%20true,并且%20y.equals(z)%20返回%20true,那么%20x.equals(z)%20應(yīng)返回%20true。

      4、一致性:對(duì)于任何非空引用值%20x%20和%20y,多次調(diào)用%20x.equals(y)%20始終返回%20true%20或始終返回%20false,前提是對(duì)象上%20equals%20比較中所用的信息沒(méi)有被修改。

      5、 對(duì)于任何非空引用值%20x,x.equals(null)%20都應(yīng)返回%20false。

       對(duì)于上面幾個(gè)規(guī)則,我們?cè)谑褂玫倪^(guò)程中最好遵守,否則會(huì)出現(xiàn)意想不到的錯(cuò)誤。

       在java中進(jìn)行比較,我們需要根據(jù)比較的類(lèi)型來(lái)選擇合適的比較方式:

      1) 對(duì)象域,使用equals方法%20。        2) 類(lèi)型安全的枚舉,使用equals或==%20。       3) 可能為null的對(duì)象域%20:%20使用%20==%20和%20equals%20。       4) 數(shù)組域%20:%20使用%20Arrays.equals%20。       5) 除float和double外的原始數(shù)據(jù)類(lèi)型%20:%20使用%20==%20。       6) float類(lèi)型:%20使用Float.foatToIntBits轉(zhuǎn)換成int類(lèi)型,然后使用==。       7) double類(lèi)型:%20使用Double.doubleToLongBit轉(zhuǎn)換成long類(lèi)型,然后使用==。

       至于6)、7)為什么需要進(jìn)行轉(zhuǎn)換,我們可以參考他們相應(yīng)封裝類(lèi)的equals()方法,下面的是Float類(lèi)的:

[java] view%20plain copy public boolean equals(Object obj) {      return (obj instanceof Float)             && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));      }  

       原因嘛,里面提到了兩點(diǎn):

[java] view%20plain copy However, there are two exceptions:  If f1 and f2 both republic class Person {      protected String name;        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }            public Person(String name){          this.name = name;      }            public boolean equals(Object object){          if(object instanceof Person){              Person p = (Person) object;              if(p.getName() == null || name == null){                  return false;              }              else{                  return name.equalsIgnoreCase(p.getName());              }          }          return false;      }  }  

       子類(lèi):Employee

[java] view%20plain copy public class Employee extends Person{      private int id;            public int getId() {          return id;      }        public void setId(int id) {          this.id = id;      }        public Employee(String name,int id){          super(name);          this.id = id;      }            /**      * 重寫(xiě)equals()方法      */      public boolean equals(Object object){          if(object instanceof Employee){              Employee e = (Employee) object;              return super.equals(object) && e.getId() == id;          }          return false;      }  }  

       上面父類(lèi)Person和子類(lèi)Employee都重寫(xiě)了equals(),不過(guò)Employee比父類(lèi)多了一個(gè)id屬性。測(cè)試程序如下:

[java] view%20plain copy 派生到我的代碼片public class Test {      public static void main(String[] args) {          Employee e1 = new Employee("chenssy", 23);          Employee e2 = new Employee("chenssy", 24);          Person p1 = new Person("chenssy");                    System.out.println(p1.equals(e1));          System.out.println(p1.equals(e2));          System.out.println(e1.equals(e2));      }  }  

       上面定義了兩個(gè)員工和一個(gè)普通人,雖然他們同名,但是他們肯定不是同一人,所以按理來(lái)說(shuō)輸出結(jié)果應(yīng)該全部都是false,但是事與愿違,結(jié)果是:true、true、false。

       對(duì)于那e1!=e2我們非常容易理解,因?yàn)樗麄儾粌H需要比較name,還需要比較id。但是p1即等于e1也等于e2,這是非常奇怪的,因?yàn)閑1、e2明明是兩個(gè)不同的類(lèi),但為什么會(huì)出現(xiàn)這個(gè)情況?首先p1.equals(e1),是調(diào)用p1的equals方法,該方法使用instanceof關(guān)鍵字來(lái)檢查e1是否為Person類(lèi),這里我們?cè)倏纯磇nstanceof:判斷其左邊對(duì)象是否為其右邊類(lèi)的實(shí)例,也可以用來(lái)判斷繼承中的子類(lèi)的實(shí)例是否為父類(lèi)的實(shí)現(xiàn)。他們兩者存在繼承關(guān)系,肯定會(huì)返回true了,而兩者name又相同,所以結(jié)果肯定是true。

       所以出現(xiàn)上面的情況就是使用了關(guān)鍵字instanceof,這是非常容易“專(zhuān)空子”的。故在覆寫(xiě)equals時(shí)推薦使用getClass進(jìn)行類(lèi)型判斷。而不是使用instanceof。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 龙里县| 宿松县| 泌阳县| 宜昌市| 额敏县| 和平区| 天水市| 鹤庆县| 彭水| 建阳市| 乌审旗| 科尔| 祁东县| 南部县| 镇原县| 安顺市| 渭南市| 贵德县| 格尔木市| 扎兰屯市| 霍林郭勒市| 紫阳县| 永吉县| 米林县| 肥东县| 湟源县| 苏尼特右旗| 白玉县| 河西区| 体育| 辉县市| 滦平县| 永年县| 淳安县| 三穗县| 盐边县| 长春市| 昭觉县| 元朗区| 玉山县| 和田县|