system.nanotime() 返回值单位为纳秒,本质是相对起始点的 long 型差值,仅用于计算耗时差值;单个值无业务意义,不可当时间戳或直接比较大小;溢出约292年发生但差值计算天然安全;实际分辨率受限于硬件,通常10–50纳秒。

System.nanoTime() 返回值的单位是纳秒(nanoseconds),本质是一个 long 类型整数,表示从某个固定但任意的起点(JVM 启动时选定)开始经过的纳秒数。
单位不是“绝对时间”,而是“相对纳秒差”
它不对应任何日历时间(比如 2026 年 6 月),也不能转成 Date 或 ISO 时间。它的唯一合法用途是:用两个调用结果相减,得到一段代码或操作的耗时——这个差值才是有意义的纳秒数。
- 例如:
long start = System.nanoTime(); doWork(); long end = System.nanoTime(); long ns = end - start; - 这个
ns值才代表真实经过的纳秒,可进一步换算为微秒、毫秒等 - 单独看
start或end的数值本身没有业务含义,甚至可能是负数(因起点可能设在未来)
long 溢出:约 292 年后会翻转
long 最大值为 2⁶³−1 ≈ 9.22 × 10¹⁸ 纳秒,换算下来约等于 292 年。这意味着:
- 如果 JVM 连续运行近三个世纪,
System.nanoTime()的返回值会从最大正数溢出为负数 - 但实际中更需警惕的是:差值计算时不能直接比较大小,比如判断
t1 是错的 - 正确做法是始终用差值判断:
t1 - t0 表示逻辑上 <code>t1发生在t0之前(仅在发生溢出时成立)
溢出对日常开发影响极小,但写法必须严谨
普通应用不可能运行 292 年,所以溢出本身几乎不会发生。真正容易出错的是开发者忽略差值语义,误把单个 nanoTime() 值当时间戳用,或错误比较大小。
- ❌ 错误:
if (t1 —— 可能因溢出导致误判 - ✅ 正确:
if (t1 - t0 —— 差值天然处理溢出,语义安全 - ⚠️ 注意:所有耗时统计必须基于同一 JVM 实例内的两次调用,跨进程/重启的值不可比
硬件分辨率限制:纳秒只是单位,不是精度
虽然单位是纳秒,但底层计时器(如 Linux 的 CLOCK_MONOTONIC 或 CPU 的 TSC)的实际分辨率通常在 10–50 纳秒量级。这意味着:
- 连续两次调用
nanoTime()可能返回相同值(尤其在空操作或短循环中) - 看到
1234567890123L这样的数值,并不意味物理时间精确到个位纳秒 - 它提供的是高分辨率单调时钟,适合测间隔;但“纳秒精度” ≠ “纳秒准确度”











