[改善Java代碼]equals應該考慮null值的情景


建議46: equals應該考慮null值情景

繼續上一建議的問題,我們解決了覆寫equals的自反性問題,是不是就很完美了呢?再把main方法重構一下:

 1 public class Client {  
 2     public static void main(String[] args) {  
 3          Person p1 = new Person("張三");  
 4          Person p2 = new Person(null);  
 5      
 6          List<Person> l =new ArrayList<Person>();  
 7          l.add(p1);  
 8          l.add(p2);  
 9          System.out.println("列表中是否包含張三:"+l.contains(p1));  
10          System.out.println("列表中是否包含張三 :"+l.contains(p2));  
11     }  
12 }  
13 
14 class Person{  
15     private String name;  
16 
17     public Person(String _name){  
18        name = _name;  
19     }  
20 
21     @Override  
22     public boolean equals(Object obj) {  
23          if(obj instanceof Person){  
24            Person p = (Person) obj;  
25            return name.equalsIgnoreCase(p.getName().trim());  
26          }  
27          return false;  
28     }
29 
30     public String getName() {
31         return name;
32     }
33 
34     public void setName(String name) {
35         this.name = name;
36     }  
37 } 

很小的改動,那運行結果是什么呢?是兩個true嗎?我們來看運行結果:

列表中是否包含張三:true
Exception in thread "main" java.lang.NullPointerException

竟然拋異常了!為什么p1就能在List中檢查一遍,並且執行p1.equals方法,而到了p2就開始報錯了呢?仔細分析一下程序,馬上明白了:當執行到p2.equals(p1)時,由於p2的name是一個null值,所以調用name. equalsIgnoreCase方法時就會報空指針異常了!出現這種情形是因為覆寫equals沒有遵循對稱性原則:對於任何引用x和y的情形,如果x.equals(y)返回true,那么y.equals(x)也應該返回true。

問題知道了,解決也很簡單,增加name是否為空進行判斷即可,修改后的equals代碼如下:

 1 public boolean equals(Object obj) {  
 2      if(obj instanceof Person){  
 3           Person p = (Person) obj;  
 4           if(p.getName()==null || name==null){  
 5             return false;  
 6           }else{  
 7             return name.equalsIgnoreCase(p.getName());  
 8         }  
 9     }  
10     return false;  
11 } 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM