相信大多数Java从业同学早都对于java的整数缓存有过了解,甚至有人踩过坑。那么有人会问java为什么会java整数进行缓存(-128~127)?
问题很常见,但是问题的出发点有问题。受java语言特性的影响,大家都认为整数对象是不相等,所以出发点也是这。但是正常的出发点应该是数学定理或常识,没有语言属性的,例如:如果a = 10,b = 10 那么就一定可以得到结果a=b。Java基础的整数变量是满足的这些特性的,但是java面向对象的语言,那么基础类型的包装对象就成了基础变量和对象之间转换的桥梁。但是作为对象的整数因为语言的限制没办法做到值对象的相等。
所以Java整数对象的缓存是为了实现相同基础类型整数应该是直接相等的技术上的折中方案,而缓存范围是[-128,127]也是为了满足大多数场景的对象共享和小型机的使用。不同的系统可以通过jvm参数-XX:AutoBoxCacheMax=<size>
自行设置装箱缓存的上限,下限还是-128。
关于java整数的缓存可以参考:JLS 5.1.7,给出java8的JLS 下面是关于包装对象缓存相关的说明:
If the valuep
being boxed is an integer literal of typeint
between-128
and127
inclusive (§3.10.1), or the boolean literaltrue
orfalse
(§3.10.3), or a character literal between'\u0000'
and'\u007f'
inclusive (§3.10.4), then leta
andb
be the results of any two boxing conversions ofp
. It is always the case thata
==
b
.
Ideally, boxing a primitive value would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rule above is a pragmatic compromise, requiring that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, the rule disallows any assumptions about the identity of the boxed values on the programmer's part. This allows (but does not require) sharing of some or all of these references. Notice that integer literals of type long are allowed, but not required, to be shared.
This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.
A boxing conversion may result in an OutOfMemoryError if a new instance of one of the wrapper classes (Boolean, Byte, Character, Short, Integer, Long, Float, or Double) needs to be allocated and insufficient storage is available.
缓存的实现
具有缓存结构的包装对象主要是java.lang.Byte
,java.lang.Character
,java.lang.Integer
,java.lang.Long
,java.lang.Short
。缓存方式都是静态数组。