我正在深入研究Integer
类实际上如何使用缓存对象,我在Integer.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);
}
我的问题是:
assert IntegerCache.high >= 127;
我的用法是什么?
assert provides an effective way to detect and correct programming
errors。但这是运行时代码所以为什么有人会使用assert?AssertionError
?答案 0 :(得分:17)
断言的目的是建立不变量并记录实现。在这里,这个断言记录了这样一个事实:当输入valueOf
方法IntegerCache.high
时,值保证至少为127.最好写一个断言而不是注释,因为断言也会被检查当相应的命令行选项(-esa
)处于活动状态时由JVM启动。
通常这个断言永远不会抛出,因为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.因此,如果您修改IntegerCache.high
(使用反射和setAccessible(true)
)或将来修改JDK,则断言可以抛出将在IntegerCache.high
初始化代码中介绍。这就是断言存在的原因:捕捉错误。
答案 1 :(得分:9)
The JLS mandates that the integer cache must be in place for integers between -128 and 127.
目前,Oracle实施强制执行此操作但不多,因此缓存上限可能会在未来的某个时间点延长(实际上不太可能,但它完全符合规范。)
然而,它永远不会少于而不是127,否则实现将不再符合JLS - 这将是一个相当大的交易,因此(我相信)为什么断言声明是有!
正如biziclop在评论中所指出的那样,用户也可以通过传递一个VM参数来改变它 - 另一个(也许是更引人注目的)断言的原因。
另请注意,除非使用-ea
运行,否则将跳过assert语句,因此在正常使用中,此检查绝对没有运行时开销。
答案 2 :(得分:6)
缓存,通常为-128 ... 127,可以放大,这可能是原因:它不应该变得更少。而且,即使没有缓存,代码也能正常工作,断言可能是一种软性方式:在开发时告诉性能缺陷。因为断言对生产代码没有影响。
答案 3 :(得分:2)
看着
http://www.docjar.com/html/api/java/lang/Integer.java.html
我看到了这条评论
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/
如果他们在valueOf
中使用了parseInt
,那么在VM初始化的早期调用parseInt
时,high
值实际上将为零。
我不确定会导致什么问题,但显然有人认为值得防范。
防止在VM初始化期间调用valueOf方法调用的代码。
如果使用-ea选项运行java(启用断言)并且有一些调用valueOf的初始化代码,由于AssertionError,JVM几乎会立即崩溃。希望Java团队测试这些东西,并在将其发布到野外之前修复有问题的代码。
与其他答案的断言相反,高位将始终大于或等于128,似乎有时它为零(不计算反射)。