如何遵循Java中值的来源?

eli*_*ner 5 java debugging

我有一个很少得到错误值的变量.由于系统非常复杂,我无法跟踪值经过的所有代码路径 - 涉及多个线程,可以保存,然后从DB加载,依此类推.我将尝试使用代码图生成器来查看是否可以通过查看setter的调用方式来发现问题,可能还有其他一些技术.也许用一个跟踪地点和变化的类来包装值?我不确定这个问题是否足够明确,但我很感激遇到这种情况的人的意见.

[编辑]问题不容易重现,我无法在调试器中捕获它.我正在寻找静态分析或记录技术来帮助追踪问题.

[编辑2]为了让事情更清楚,我所说的值是一个时间戳,表示为64位长变量中Unix纪元(01/01/1970)的毫秒数.在某个未知点,该值的前32位被截断,产生完全不正确(和不可恢复)的时间戳.

[编辑3]好的,感谢您的一些建议以及几个小时的代码,我找到了罪魁祸首.通过将基于毫秒的时间戳除以1000并将其存储在int变量中,将基于毫秒的时间戳转换为基于秒的时间戳.在代码的稍后时刻,基于秒的时间戳(an int)乘以1000并存储到新long变量中.由于1000和第二个时间戳都是int值,因此乘法的结果在转换为long之前被截断.这是一个微妙的,感谢所有帮助过的人.

Dav*_*itz 6

如果您使用setter 并且只使用setter来设置值,则可以添加这些行以跟踪线程和堆栈跟踪:

public void setTimestamp(long value) {
  if(log.idDebugEnabled) {
    log.debug("Setting the value to " + value + ". Old value is " + this.timestamp);
    log.debug("Thread is " + Thread.currentThread().getName());
    log.debug("Stacktrace is", new Throwable()); // we could also iterate on Thread.currentThread().getStackTrace()
  }
  // check for bad value
  if(value & 0xffffffff00000000L == 0L) {
    log.warn("Danger Will Robinson", new IlegalValueException());
  }
  this.timestamp = value;
}
Run Code Online (Sandbox Code Playgroud)

另外,遍历包含该字段的类,并确保每个对它的引用都是通过setter完成的(即使在private/protected方法中)

编辑

也许FindBugs可以在静态分析方面提供帮助,我会稍后尝试找到确切的规则.