You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Calendar类toString方法返回数据不一致问题求助

Java Calendar.toString() 输出不一致的原因分析

这段测试代码里,两次完全相同的断言结果却截然不同:第一次执行成功,但在调用calendar.get(Calendar.DAY_OF_YEAR)后,第二次断言直接失败。我已经找到问题的规避方法,最初推测是toString()方法存在bug,实际是Calendar的设计特性导致的差异。

测试代码如下:

// Calendar calendar = new Calendar.Builder().setDate(2024, Calendar.JANUARY, 25).build();
Calendar calendar = Calendar.getInstance();
calendar.set(2024, Calendar.JANUARY, 25);
assertThat(calendar.toString(), not(containsString("DAY_OF_YEAR=25"))); // success
assertEquals(25, calendar.get(Calendar.DAY_OF_YEAR)); // success
assertThat(calendar.toString(), not(containsString("DAY_OF_YEAR=25"))); // fail

核心原因

Calendar采用延迟计算的设计逻辑:

  • 调用set()方法设置年月日时,Calendar仅记录这些显式设置的字段,不会立刻计算派生字段(比如DAY_OF_YEAR)。
  • 第一次调用toString()时,输出的只有已显式设置的字段,此时DAY_OF_YEAR还未被计算,所以输出里没有这个字段,断言成功。
  • 当调用get(Calendar.DAY_OF_YEAR)时,Calendar会触发全字段同步计算,DAY_OF_YEAR会被计算为25并缓存下来。
  • 第二次调用toString()时,已缓存的DAY_OF_YEAR字段会被包含在输出中,导致断言失败。

这并非toString()的bug,而是Calendar为了性能优化采用的延迟计算机制,引发了前后两次输出的差异。

内容的提问来源于stack exchange,提问作者Ilya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:12:07