专业编程基础技术教程

网站首页 > 基础教程 正文

int被定义为Integer,导致程序死循环,了解底层代码有多重要

ccvgpt 2024-08-06 12:37:05 基础教程 59 ℃

前言:春节期间,坐在公司加班,本以为可以坐在那看看日志,打打游戏,聊会天一天就过去了,突然加群里我,为什么我的任务执行了快一上午了,怎么还是处理中。

我随便应付说,可能是数据量大,执行时间长呗,过了2个小时还是没执行完,立即查看日志,发现一个Exception都没有,在看看log中是否打印了执行完毕的输出,发现没有,立马慌了。

int被定义为Integer,导致程序死循环,了解底层代码有多重要

当时真是脑袋翁的一下,这是啥问题,报个错也行呀。在本地项目中跑跑试试看,还是没发现问题,依旧不打印执行完毕的日志。

那我就看看是不是判断出问题了,在判断的地方打印出前后比较的值,发现从128开始,128!=128,返回为false。

这是什么情况?


开始真的认为不可能呀,基本类型比较怎么还出现false了呢。后来一看代码。我把int定义成了Integer。瞬间明白了为什么?

大家都知道Integer是有缓存的,当数值在-128~127之间,是从缓存中取数据。

/**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

所有给大家做一个测试


public class IntegerTest {
    static Map<String, String> first = new HashMap<>();
    public void testNum(Integer num) {
        System.out.println(first.get("count" )+ "//" + num);
        System.out.println(Integer.valueOf(first.get("count")) == num);
    }

    public int pageCount() {
        return 128;
    }

    public static void main(String[] args) {
        IntegerTest t = new IntegerTest();
        final int str = t.pageCount();
        first.put("count", "127");
        int f = Integer.valueOf(first.get("count"));
        int ff = f + 1;
        first.put("count", ff + "");
        t.testNum(str);
    }
}

程序输出

128//128
false

我们将上面的入参修改为int:


public class IntegerTest {
    static Map<String, String> first = new HashMap<>();
    public void testNum(int num) {
        System.out.println(first.get("count" )+ "//" + num);
        System.out.println(Integer.valueOf(first.get("count")) == num);
    }

    public int pageCount() {
        return 128;
    }

    public static void main(String[] args) {
        IntegerTest t = new IntegerTest();
        final int str = t.pageCount();
        first.put("count", "127");
        int f = Integer.valueOf(first.get("count"));
        int ff = f + 1;
        first.put("count", ff + "");
        t.testNum(str);
    }
}

程序运行结果就正确了

128//128
true

总结:还好当时知道Integer的源码,看见128之后,想到了Integer的缓存,不然真的得找一会原因了。当你在面临压力面前还能心里不急躁的去找bug是办不到的,所以平时还是需要看看源码,另外,这纯是一种马虎行为,大家在平时开发一定要注意下。

最近发表
标签列表