[改善Java代码]equals应该考虑null值的情景
建议46: equals应该考虑null值情景
继续上一建议的问题,我们解决了覆写equals的自反性问题,是不是就很完美了呢?再把main方法重构一下:
public class Client {
public static void main(String[] args) {
Person p1 = new Person("张三");
Person p2 = new Person(null);
List<Person> l =new ArrayList<Person>();
l.add(p1);
l.add(p2);
System.out.println("列表中是否包含张三:"+l.contains(p1));
System.out.println("列表中是否包含张三 :"+l.contains(p2));
}
}
class Person{
private String name;
public Person(String _name){
name = _name;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Person){
Person p = (Person) obj;
return name.equalsIgnoreCase(p.getName().trim());
}
return false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
很小的改动,那运行结果是什么呢?是两个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代码如下:
public boolean equals(Object obj) {
if(obj instanceof Person){
Person p = (Person) obj;
if(p.getName()==null || name==null){
return false;
}else{
return name.equalsIgnoreCase(p.getName());
}
}
return false;
}
[改善Java代码]equals应该考虑null值的情景的更多相关文章
- [改善Java代码]提防包装类型的null值
建议26: 提防包装类型的null值 我们知道Java引入包装类型(Wrapper Types)是为了解决基本类型的实例化问题,以便让一个基本类型也能参与到面向对象的编程世界中.而在Java 5中泛型 ...
- [改善Java代码]别让null值和空值威胁到变长方法
建议5:别让null值和空值威胁到变长方法 public class Client { public void methodA(String str,Integer... is){ } public ...
- [改善Java代码]不要在finally块中处理返回值
在finally代码块中处理返回值,这是在面试题中经常出现的题目.但是在项目中绝对不能再finally代码块中出现return语句,这是因为这种处理方式非常容易产生"误解",会严重 ...
- [改善Java代码]非稳定排序推荐使用List
我们知道Set与List的最大区别就是Set中的元素不可以重复(这个重复指的equals方法的返回值相等),其他方面则没有太大的区别了,在Set的实现类中有一个比较常用的类需要了解一下:TreeSet ...
- [改善Java代码]用枚举实现工厂方法模式更简洁
工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到 ...
- [改善Java代码]不同的场景使用不同的泛型通配符
Java泛型支持通配符(Wildcard),可以单独使用一个"?"表示任意类,也可以使用extends关键字标识某一类(接口)的子类型,还可以使用super关键字标识某一类(接口) ...
- [改善Java代码]避免带有变长参数的方法重载
建议4: 避免带有变长参数的方法重载 在项目和系统的开发中,为了提高方法的灵活度和可复用性,我们经常要传递不确定数量的参数到方法中,在Java 5之前常用的设计技巧就是把形参定义成Collection ...
- [改善Java代码]自由选择字符串拼接方法
对一个字符串拼接有三种方法:加号,contact方法,StringBuffer或者StringBuilder的append方法,其中加号是最常用的.其他两种方式偶尔会出现在一些开源项目中,那么这三者有 ...
- [改善Java代码]正确使用String,StringBuffer,StringBuilder
CharSequence接口有三个实现类与字符串有关:String,StringBuffer,StringBuffer.虽然它们都与字符串有关,但是其处理机制是不同的. String类是不可改变的量, ...
随机推荐
- Android问题-No resource found that matches the given name (at 'theme' with value '@style/CaptureTheme').
问题现象:在看一个实例中写到的,提示如下: [PAClient Error] Error: E2312 C:\Users\zhujq-a\Desktop\Android实例之实现扫描二维码并生成二维码 ...
- 回车跳到下一个EDIT
1.按下方法procedure TForm2.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin if Key ...
- Spring Auto-Wiring Beans with @Autowired annotation
In last Spring auto-wiring in XML example, it will autowired the matched property of any bean in cur ...
- poj 1236 Network of Schools(连通图入度,出度为0)
http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- Linux date命令 - 显示和设置系统日期与时间
操作系统上的时间也许只是当做一个时钟.特别在控制台下, 我们通常并不认为时间有什么重要的.但是对于管理员,这种认识是错误的.你知道错误的日期和时间会导致你不能编译程序么? 因为日期和时间很重要,这或许 ...
- UVaLive 7269 Snake Carpet (找规律,模拟)
题意:给定一个数字n,表示有n条蛇,然后蛇的长度是 i ,如果 i 是奇数,那么它只能拐奇数个弯,如果是偶数只能拐偶数个,1, 2除外,然后把这 n 条蛇, 放到一个w*h的矩阵里,要求正好放满,让你 ...
- Line去年营收超5亿美元 远超竞争对手WhatsApp
原文地址: http://news.cnblogs.com/n/206072/ 凭借着修改表情取悦国际用户的做法,日本移动消息应用 Line 在全球的用户总数已经超过 4 亿.Line.微信.What ...
- ADO.NET 快速入门(十三):使用 OLE DB 检索数据
OleDbDataReader 类提供了一种从数据源读取数据记录只进流的方法.如果想使用 SQL Server 7.0 或者更高版本,请参考文章:使用 SQL Server 检索数据. OleDb ...
- 【转】部署web项目到weblogic上启动错误
启动weblogic报错:java.lang.ClassCastException: com.sun.faces.application.WebappLifecycleListener cannot ...
- 读取AD模拟分量
//EEPROM数据保存---------------------- #include <EEPROM.h> #define EEPROM_write(address, p) {int i ...