跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何在 Java 中通过 Double.valueOf() 相比 parse 更好地利用变量包装类的对象缓存

Double.valueOf() 不提供对象缓存,每次调用均创建新实例(NaN/无穷大除外);其优势在于返回Double引用类型、语义清晰、避免隐式装箱开销。 Double.valueOf() 本身 不提供对象缓存 ,这是关键前提。和 Integer、Long 不同,Java 的 Double(以及 Float)包装类 没有实现值范围内的对象缓存机制 。所以,无论你传入 "1.0"、"3.14" 还是 "123.456",每次调用
Double.valueOf("...")
都会创建一个新的
Double
实例(除非字符串表示的是 NaN 或无穷大——它们有特殊单例,但非常规数值不参与缓存)。 为什么 Double 没有像 Integer 那样的缓存? JLS(Java语言规范)只要求对
byte
、
short
、
int
、
long
和
char
的包装类在特定小范围内做缓存,而
float
和
double
明确被排除在外。原因包括: 浮点数精度问题导致“相等”判断不可靠(例如
0.1 + 0.2 != 0.3
),缓存依据难以定义; 浮点数值空间极大且稀疏,缓存实用价值低、内存开销高; 历史设计选择:JDK 开发者认为对 double 做缓存收益远小于成本。 那 Double.valueOf() 相比 parseDouble() 的实际优势在哪? 虽然没缓存,但
Double.valueOf(String)
仍有明确用途优势: 返回类型直接是
Double
,适合需要引用类型的地方:放进
Map
、作为
Optional
的值、配合泛型方法或反射使用; 语义更清晰 :表达“我要一个 Double 对象”,而不是“我要一个 double 值再让它自动装箱”; 避免隐式装箱开销与潜在空指针风险 :若你写
Double d = Double.parseDouble(str)
,JVM 会先解析出
double
,再调用
Double.valueOf(double)
装箱——多一次方法调用,且如果后续操作依赖对象非空(如调用
d.toString()
),而
parseDouble
本身不会返回 null,这点虽不构成风险,但
valueOf
的意图更纯粹。 如果你真想复用 Double 对象,可以怎么做? 标准库不提供,但你可以自行构建轻量缓存(仅适用于有限、可枚举的场景): Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”; 对固定常量(如
0.0
、
1.0
、
Math.PI
)直接用静态 final 字段; 对业务中高频出现的有限小数(如货币精度两位的小数:0.00 ~ 99.99),可用
ConcurrentHashMap
缓存解析结果; 注意:缓存 key 应统一格式(如保留两位小数并舍入),避免因字符串差异("1.0" vs "1.00")导致重复创建。 总之,Double.valueOf() 的价值不在缓存,而在类型安全、语义明确和 API 适配性。期待它像 Integer 那样缓存小数值,是误解了 Java 包装类的设计边界。

相关文章