为什么javadoc的Double.value说它caching价值,当它不?
在OpenJDK中,对于方法:
public static Double valueOf(double d)
javadoc说:
返回一个Double实例,表示指定的double值。 如果不需要新的Double实例,则通常应该优先使用此方法(优先于构造函数Double(double)),因为此方法通过caching频繁请求的值可能会产生显着更好的空间和时间性能。
这是实际的代码:
public static Double valueOf(double d) { return new Double(d); }
caching是一个谎言! 这里发生了什么?
该方法存在许多types: Integer
, Long
, BigDecimal
等,文档总是相同的:在某些情况下(没有定义),该方法可以返回相同的结果。
AFAIK,caching只对整数types实现,并返回caching实例的-128到127(最常见的值)之间的值。 对于BigDecimal
,caching当前适用于从0到10的值。
Java的更高版本可能会将此行为扩展到其他值/更多types。 所以,今天使用这个代码是很明智的,因为它可能会使你的代码在明天更快(而且代码今天不会太慢)。
例如,Java编译器在生成自动装箱代码时使用此API。
API文档没有任何问题:
这种方法很可能会产生…
也就是说,一个实现被允许在这里进行caching,这对构造函数来说是不可能的。 但是,这不是必需的。 但是,由于你有一个执行caching的实现,所以这个方法应该优于使用构造方法。
从Java 1.5+开始,JVM / JIT保证Integer
的高速caching-127到127.所以对于Integer
,首选的方法是使用valueOf
。 您通常应该使用valueOf
来使用double
的构造函数,因为那样的话JIT可以根据自己的需要优化代码。 例如,考虑下面的循环:
for (Object o: objectList) { o.setValue(Double.valueOf(0.0)); }
在这种情况下,JIT可以预先计算双重对象,并在循环的每次迭代中重新分配相同的值,而如果您要使用new Double(0.0);
它将无法做到这一点。
API的devise者可能不想限制替代实现。 那些现在可以向Double
类添加caching。
这些valueOf()
方法存在于每个数字types中,以支持caching。 实际上,对于Double,它不使用任何caching,但是对于Integer
和Long
。
请记住,创buildJVM是为了减lessembedded式设备(主要是)的代码大小 – 这是一个机顶盒操作系统。 我曾经在一些embedded式java平台上工作过,对那些“valueOf”值更为明显,在某些情况下会节省相当多的空间。
大多数方法存在,因为“新”永远不能使用caching的实例。 valueOf可能被实现为使用caching的实例(否则你只是总是使用新的),并可能在任何地方certificate,以节省时间。
如果他们(或者你)用一个实际上caching值的方法replace了那个方法,那么你所有的代码都会从这个变化中获得好处,但是如果没有通过提供像“valueOf”这样的方法来准备,它就永远不会发生(实际上,你可以调整编译器/字节码的执行者有“新”返回caching值,但我认为这将打破一些合同)
所以caching不是一个谎言,只是一个心态。