当前位置: 首页 > 技术随笔 > Java String equals()方法一个值得注意的细节

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

最近朋友在编写程序代码并进行相关测试时发现,有一段程序代码老是无法按照编写代码时所期望的逻辑执行。业务逻辑是:当雇员的业务状态(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()方法,其中又做了哪些处理。

19 0
我们认为: 用户的主要目的,是为了获取有用的信息,而不是来点击广告的。因此本站将竭力做好内容,并将广告和内容进行分离,确保所有广告不会影响到用户的正常阅读体验。用户仅凭个人意愿和兴趣爱好点击广告。
我们坚信:只有给用户带来价值,用户才会给我们以回报。
CodePlayer技术交流群1CodePlayer技术交流群1

帮朋友打一个硬广告:

P2P网贷系统(Java版本) 新年低价大促销,多年P2P技术积累,系统功能完善(可按需定制,可支持第三方存管、银行存管),架构稳定灵活、性能优异、二次开发快速简单。 另可提供二次开发、安装部署、售后维护、安全培训等一条龙服务。

外行看热闹,内行看门道。可以自信地认为,在系统设计上,比市面上的晓风、迪蒙、方维、绿麻雀、国融信、金和盛等P2P系统要好。
深圳地区支持自带技术人员现场考察源代码、了解主要技术架构,货比三家,再决定是否购买。

也可推荐他人购买,一旦完全成交,推荐人可获得实际售价 10% 的返现。
有意向者,详情请 点击这里 联系,工作时间立即回复。