为什么在 Integer 类的 Integer.valueOf 方法中使用断言?

2022-09-01 17:28:56

我正在深入研究该类实际如何使用缓存对象,并在该方法中找到了以下代码:IntegerInteger.valueOf

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

我的问题是:


答案 1

断言的目的是建立不变量并记录实现。此处,此断言记录了这样一个事实,即当输入方法时,值保证至少为 127。最好编写断言而不是注释,因为当相应的命令行选项 () 处于活动状态时,JVM 也会检查断言。valueOfIntegerCache.high-esa

通常,此断言永远不会抛出,因为 是以这种方式初始化的:IntegerCache.high

int h = 127;
String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
    try {
        int i = parseInt(integerCacheHighPropValue);
        i = Math.max(i, 127);
        // Maximum array size is Integer.MAX_VALUE
        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
    } catch( NumberFormatException nfe) {
        // If the property cannot be parsed into an int, ignore it.
    }
}
high = h;

此代码保证该值至少为 127。因此,如果您修改(使用反射和),或者将来将修改JDK并在初始化代码中引入错误,则可以抛出断言。这就是断言存在的原因:捕获错误。IntegerCache.highsetAccessible(true)IntegerCache.high


答案 2

JLS 要求对于介于 -128 和 127 之间的整数,整数缓存必须到位。

目前,Oracle实现强制执行这一点,但不再强制执行,因此缓存上限很可能在未来的某个时候扩展(在实践中不太可能,但它将完全符合规范)。

但是,它永远不会小于127,否则实现将不再符合JLS - 这将是一个相当大的问题,因此(我相信)为什么断言语句在那里!

正如 biziclop 在注释中指出的那样,用户也可以通过传递 VM 参数来更改它 - 这是断言到位的另一个(也许是更令人信服的)原因。

另请注意,除非与 一起运行,否则将跳过 assert 语句,因此在正常使用中,此检查绝对没有运行时开销。-ea