前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 记一次自定义比较器中compareTo方法使用long强转int作为比较结果产生的bug

Java 记一次自定义比较器中compareTo方法使用long强转int作为比较结果产生的bug

作者头像
heasy3
发布2020-08-02 12:49:38
1.3K0
发布2020-08-02 12:49:38
举报

最近换了新工作,改bug作为熟悉业务及代码的快速途径,是每个新人都要经历的

代码不难,难的是业务不熟,很多地方不知道为什么要这么写。当然,时间久了就好了


这次要找的bug是排序问题,前端请求接口,按某个字段排序后,返回的结果总是很怪异,数据最多的那个总是与排序要求相反。

比如升序排序,他会跑到最后一页的最后一条

降序排序会跑到第一条

捋代码发现他的排序逻辑如下:

请求参数:orderBy=validCount&sortType=desc&currentPage=1

代码语言:javascript
复制
//controller封装参数调用service的查询
//service查询出全部,进行排序后,根据分页参数进行逻辑分页
    Collections.sort(listIntelSourceListVos);
    return new Pager<>(currentPage, pageSize, listIntelSourceListVos);

这个list中存放的类定义如下:

代码语言:javascript
复制
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class IntelSourceListVo extends ComparableImpl<IntelSourceListVo> {
    private int sourceId;
    private String sourceName;
    private int sourceType;
    private String intelType;
    private String intelUri;
    private long validCount;
    private long totalCount;
    private String createtime;
    private String lastEnteringTime;
    private int status;
    private int weight;
    private Integer isStart;
}

它实现的comparableImpl为一个自定义的排序类,实现这个排序类的类可以根据类中的sortType来进行排序,orderBy进行升序与降序的控制。其中用到了一些简单的反射。

代码语言:javascript
复制
package cn.threatbook.tim.vo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;

@Setter
@Getter
@NoArgsConstructor
public class ComparableImpl<T> implements Comparable<T> {
    @JsonIgnore
    String sortType;

    @JsonIgnore
    String orderBy;

    @Override
    public int compareTo(T that) {
        if (orderBy == null) {
            return 0;
        }

        int order = -1;
        if ("desc".equals(sortType)) {
            order = 1;
        }

        try {
            Class clazz = that.getClass();
            Field field = clazz.getDeclaredField(orderBy);
            field.setAccessible(true);
            Object thisValue = field.get(this);
            Object thatValue = field.get(that);

            String valueType = field.getType().toString();
            if (valueType.endsWith("String")) {
                String thisValueStr = (String) thisValue;
                String thatValueStr = (String) thatValue;

                if (StringUtils.isEmpty(thisValueStr)
                        && StringUtils.isEmpty(thatValueStr)) {
                    return 0;
                } else if (StringUtils.isEmpty(thisValueStr)) {
                    return order;
                } else if (StringUtils.isEmpty(thatValueStr)) {
                    return -order;
                }

                return -thisValueStr.compareTo(thatValueStr) * order;
            } else if (valueType.endsWith("long") || valueType.endsWith("Long")) {
                //bug出现处
                long thisValueLong = (long) thisValue;
                long thatValueStr = (long) thatValue;//这随意的变量命名....
                return (int) (thatValueStr - thisValueLong) * order;
            } else if (valueType.endsWith("int") || valueType.endsWith("Integer")) {
                int thisValueLong = (int) thisValue;
                int thatValueStr = (int) thatValue;
                return (thatValueStr - thisValueLong) * order;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return 0;

    }

}

由于请求参数orderBy=validCount&sortType=desc&currentPage=1 中指定了的排序字段是validCount

且该实体类的validCount字段为long类型,可知排序肯定在long类型比较的代码块中进行。

断点debug到long类型进行比较的部分 发现了该bug产生的原因。主要原因是当两个值进行相减后

比如2822920460-1 结果依旧大于Integer.MAX_VALUE ,在进行int强转后,返回的结果不准确。

代码语言:javascript
复制
    public static void main(String[] args) {
        long l = -2822920460L;
        System.out.println((int) l);
        l = 2822920460L;
        System.out.println((int) l);
    }

输出的结果为:

可以看到符号正好是相反的。

将代码进行修改后 完成。

今天又修好了一个bug 也少了几根头发

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 今天又修好了一个bug 也少了几根头发
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档