Java中Float与Double的常见值缓存实例使用范围有多大?
Float & Double的valueOf缓存:和Integer大不一样
Great question! Let's clarify how Float.valueOf() and Double.valueOf() handle caching compared to integer types like Integer:
- 核心结论:和Integer、Byte等整数类型(Java规范强制要求缓存-128到127的实例)不同,
Float.valueOf()和Double.valueOf()不会缓存固定范围的数值实例——哪怕是像0.0、1.0这类高频使用的浮点数,主流JDK实现里每次调用都会生成新的对象。
你提到Javadoc里说该方法“可能使用缓存值”,这其实是Java规范给实现者留的灵活空间,并没有强制要求必须做缓存。实际情况是:
如果不需要新的Float实例,通常应优先使用此方法而非构造方法Float(float),因为该方法通过缓存频繁请求的实例,可能在空间和时间性能上带来显著提升……
这段描述更像是一种“前瞻性”的说明,允许未来的JDK版本如果有合适的场景可以添加缓存,但截至目前(包括OpenJDK、Oracle JDK的最新版本),Float和Double的valueOf并没有实现任何缓存逻辑。
为什么会这样?主要是浮点数的特性决定的:
- 浮点数的取值范围极大,从极小的接近0的数到极大的数值,没有像整数那样集中的“高频使用小范围”;
- 缓存浮点数实例的内存收益极低,甚至可能因为维护缓存带来额外的性能开销,完全得不偿失。
用代码验证一下就很清楚:
// Float的情况:每次valueOf都生成新实例 Float f1 = Float.valueOf(0.0f); Float f2 = Float.valueOf(0.0f); System.out.println(f1 == f2); // 输出 false // Integer的情况:复用缓存实例 Integer i1 = Integer.valueOf(100); Integer i2 = Integer.valueOf(100); System.out.println(i1 == i2); // 输出 true
不过还是推荐优先使用Float.valueOf()和Double.valueOf()而不是构造方法,一来这是Java规范推荐的工厂方法模式,二来如果未来JDK实现了缓存优化,你的代码可以无缝受益。
内容的提问来源于stack exchange,提问作者Tordanik
相关产品推荐
相关产品推荐

