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

clojure.java-time解析字符串为日期时特定函数调用出现空指针异常

异常诱因

从栈顶java.lang.Class/isAssignableFrom抛出空指针可以直接定位根因:java-time库做输入类型检查时,拿到的输入值为nil,调用class方法取nil的类型返回null,触发了空指针异常。

你观察到打印time2能得到合法时间格式,有三种常见的实际场景:

  • 你只检查了第二个入参time-last-similar,但第一个入参time实际为nil
  • similar-transactions过滤结果为空时,(first similar-transactions)返回nil,你打印的是其他正常分支的日志,不是报错那次的入参
  • 少数情况:你传入的时间值是延迟求值对象(比如未取值的delay、懒序列元素),打印时触发求值得到了合法值,但time/instant解析时没有对应处理逻辑,内部取值得到nil

另外你编写的doubled-transaction?本身存在逻辑漏洞:没有匹配的相似交易时,time-last-similar必然是nil,直接传给时间差计算函数一定会触发报错。

解决方法
  1. 优先加空值防护,在调用时间差函数前判断所有入参非空,同时处理无相似交易的边界情况:
(defn doubled-transaction? [merchant amount time transactions]
  ;; 前置校验必要入参非空
  (when (and time (seq transactions))
    (let [similar-transactions (filter (has-values :merchant merchant :amount amount) transactions)
          time-last-similar (:time (first similar-transactions))]
      ;; 存在相似交易再做时间差判断
      (when time-last-similar
        (< (calculate-time-diff time time-last-similar) 120)))))
  1. 如果存在延迟求值的时间值,可在calculate-time-diff内部加强制取值和空值校验:
(defn calculate-time-diff [time1 time2]
  ;; 前置断言入参非空,提前暴露问题
  {:pre [(some? time1) (some? time2)]}
  (let [;; force兼容普通值和延迟求值对象
        parsed-time1 (time/instant (force time1))
        parsed-time2 (time/instant (force time2))]
    (time/time-between parsed-time1 parsed-time2 :seconds)))
  1. 如果排查确认入参非空仍报错,就是java-time识别不了入参的时间类型,可显式转成字符串再解析:
(time/instant (str time-val))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:30:04