您的浏览器过于古老 & 陈旧。为了更好的访问体验, 请 升级你的浏览器
Ready 发布于2013年08月09日 06:16

原创 Java String equals()方法一个值得注意的细节

2214 次浏览 读完需要≈ 7 分钟

内容目录

最近朋友在编写程序代码并进行相关测试时发现,有一段程序代码老是无法按照编写代码时所期望的逻辑执行。业务逻辑是:当雇员的业务状态(status)为2时,执行if语句块中对应的程序代码。示例代码如下:

/**
 * 从数据库中获取雇员数据,并以Map<String, Object>形式返回
 * @return
 */
public Map<String, Object> getEmp() {
    ResultSet rs = null;
    /*
     * 这里省略建立数据库连接管理以及SQL语句执行的相关代码
     */
    Map<String, Object> employeeMap = null;
    if (rs.next()) {
        employeeMap = new HashMap<String, Object>();
        employeeMap.put("name", rs.getObject("name")); // 姓名
        employeeMap.put("age", rs.getObject("age")); // 年龄
        employeeMap.put("status", rs.getObject("status")); // 业务状态
    }
    return employeeMap;
}

/**
 * 处理相关业务逻辑
 */
public void process() {
    Map<String, Object> emp = getEmp();
    if (emp != null) {
        Object status = emp.get("status");
        if ("2".equals(status) || "4".equals(status)) {
            System.out.println("如果符合条件,执行相应业务逻辑代码……");
        } else {
            System.out.println("如果不符合条件,执行相应业务逻辑代码……");
        }
    }
}

朋友发现,即使数据库中存储的status字段值为2,程序仍然不会执行“符合条件”的部分业务逻辑代码,但是却找不到问题所在。

其实,问题就出在String类的equals()方法上。众所周知,equals(Object anObject)方法的参数只有一个,并且是Object类型的。因为String类实际上是重写了所有Java类的老祖宗java.lang.Objectequals(Object anObject)方法。

在这里需要注意的是,字段status在数据库中的类型为整数类型,当我们使用ResultSetgetObject()方法来获取该类型数据时,实际上得到的数据对象可能是IntegerLongBigDecimal等类型。不过,我们再查看一下Stringequals()方法的源代码:

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;
}

从源代码中,我们可以很清楚地看到,String类的equals()方法虽然接收的参数是Object类型,但是比较的时候却只和同样为String类型的对象比较,如果不是String类型,直接返回false。之所以参数为Object,而不是String,只是为了重写Object类的equals()方法的需要。

因此,在我们以后进行字符串的比较时,一定要多留一个心眼,如果用于比较的对象不是String类型(例如IntegerDouble等),应该根据实际情况考虑是否需要转换为String类型,再进行比较。如果比较的对象是任意类型,而我们的业务逻辑是,只需要和String类型的对象进行比较即可,那么就不需要转换;如果传递进来的对象不管是什么类型,都需要判断其字符串值(toString(),注意对象为null的情况)是否相等,则需要进行强制转换后再进行比较。

此外,在将需要比较的对象转为String类型时,也要注意该对象是否重写了Object类的toString()方法,其中又做了哪些处理。

  • CodePlayer技术交流群1
  • CodePlayer技术交流群2

0 条评论

撰写评论