最近在维护华中科技大学电信系的电子档案库,发现了一个隐藏了将近2年的Bug,记录如下:
需求:一个科研项目有一定的工作量,而每个项目有很多参与人,需要为每个参与人设置其工作量分配额度。当用户添加了一个项目时,需要同时添加其参与人:
实现:当用户录入了科研项目信息之后,点击“添加参与人”的按钮,转向到选择参与人的页面,可以勾选任意数目的参与人,点击“保存”按钮后返回科研项目信息页面。
在执行保存选择的参与人信息时,检查所选择的人员是否已经在科研项目的参与人中存在的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | for (Iterator<string> iterator = selectedMemberList.iterator(); iterator.hasNext();) { ParticipatorBean participatorBean = new ParticipatorBean(); long teacherId = Long.parseLong(iterator.next()); Teacherbasicinfo teacher = ServiceProvider.getTeacherInfoService().findById(teacherId); Long id = teacher.getTeacherId(); participatorBean.setTeacherId(id); participatorBean.setTeacherName(teacher.getTeacherName()); if (participatorsMap.get(id) == null) { participatorsMap.put(String.valueOf(id), String.valueOf(id)); participators.add(participatorBean); } } </string> |
其中,selectedMemberList是选中的用户列表,ParticipatorBean是用来传递给前一个页面的参与人的Java类,Teacherbasicinfo是领域模型,代表教师基本信息,老师编号teacherId为Long型。
participatorsMap是我从来去除重复的一个HashMap
这段代码无编译异常、无运行异常,但是却有逻辑异常。有用户反映。多次选择的时候会有重复的项出现。
经过多番调试,最后发现第八行代码有误,应该将
1 | if (participatorsMap.get(id) == null) { |
改成为:
1 | if (participatorsMap.get(String.valueOf(id)) == null) { |
恍然大悟,虽然我使用的是范型,但是Map的get方法仍然接受的是Object类型的参数,不对其参数进行检查,其put方法的签名为V put(K key, V value),则会对key和value的类型都进行检查。
这是我的错呢,还是Java的错,为啥不把get方法的参数用范型类型检查一下呢?可能是sun的工程师有别的考虑吧。
1 条评论 »
周导真辛苦。。
[回复]
评论 由 zluyuer — 2010年01月31日 #