在Java 8流中使用交互式调试器的问题 [英] Problems using interactive debuggers with Java 8 streams

查看:111
本文介绍了在Java 8流中使用交互式调试器的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 8流.它们直观,强大而优雅.但是它们确实存在IMO的一个主要缺点:它们使调试变得更加困难(除非您只能通过调试lambda表达式来解决问题,请通过

I love Java 8 streams. They are intuitive, powerful and elegant. But they do have one major drawback IMO: they make debugging much harder (unless you can solve your problem by just debugging lambda expressions, which is answered here).

请考虑以下两个等效片段:

Consider the following two equivalent fragments:

int smallElementBitCount = intList.stream()
    .filter(n -> n < 50)
    .mapToInt(Integer::bitCount)
    .sum();

int smallElementBitCount = 0; 
for (int n: intList) {
    if (n < 50) {
        smallElementBitCount += Integer.bitCount(n);
    }
}

我发现第一个更清晰,更简洁.但是,请考虑结果与预期不符的情况.你做什么工作?

I find the first one much clearer and more succinct. However consider the situation in which the result is not what you were expecting. What do you do?

在传统的迭代样式中,您在totalBitCount += Integer.bitCount(n);行上放置一个断点,并逐步遍历列表中的每个值.您可以看到当前列表元素是什么(监视n),当前总数(监视totalBitCount),以及取决于调试器的Integer.bitCount的返回值是什么.

In the traditional iterative style, you put a breakpoint on the totalBitCount += Integer.bitCount(n); line and step through each value in the list. You can see what the current list element is (watch n), the current total (watch totalBitCount) and, depending on the debugger, what the return value of Integer.bitCount is.

在新的流样式中,所有这些都是不可能的.您可以在整个语句上放置一个断点,然后逐步执行sum方法.但是总的来说,这几乎是无用的.在这种情况下,在我的测试中,我的调用堆栈深达11个,其中10个是我不感兴趣的java.util方法.无法单步执行代码测试谓词或执行映射.

In the new stream style all of this is impossible. You can put a breakpoint on the entire statement and step through to the sum method. But in general this is close to useless. In this situation in my test my call stack was 11 deep of which 10 were java.util methods that I had no interest in. It is impossible to step through the code testing predicates or performing the mapping.

调试流问题迭代调试器可以很好地破坏内部lambda表达式(例如n < 50谓词).但在许多情况下,最合适的断点不在lambda内.

It is noted in the answers to Debugging streams question that iteractive debuggers work fairly well for breaking inside lambda expressions (such as the n < 50 predicate). But in many situations the most appropriate breakpoint is not within a lambda.

很显然,这是调试的简单代码.但是,一旦添加了自定义的缩减和集合,或更复杂的过滤器和地图链,它就可能成为调试的噩梦.

Clearly this is a simple piece of code to debug. But once custom reductions and collections are added, or more complex chains of filters and maps, it can become a nightmare to debug.

我已经在NetBeans和Eclipse上进行过尝试,而且似乎都存在相同的问题.

I have tried this on NetBeans and Eclipse and both seem to have the same issues.

在过去的几个月中,我已经习惯于使用.peek调用进行调试,以记录临时值或将临时步骤移至其自己的命名方法中,或者在极端情况下,将其重构为迭代,直到找出所有错误为止.这行得通,但它让我想起了在具有集成交互式调试器的现代IDE之前的糟糕时光,那时您不得不通过代码分散printf语句.

Over the last few months I've got used to debugging using .peek calls to log interim values or moving interim steps into their own named methods or, in extreme cases, refactoring as iteration until any bugs are sorted out. This works but it reminds me a lot of the bad old days before modern IDEs with integrated interactive debuggers when you had to scatter printf statements through code.

当然有更好的方法.

我特别想知道:

  • 其他人也遇到过同样的问题吗?
  • 有没有可用的流感知"交互式调试器?
  • 是否有更好的技术来调试这种样式的代码?
  • 这是将流的使用限制为简单情况的原因吗?

您发现成功的任何技术将不胜感激.

Any techniques that you have found successful would be much appreciated.

推荐答案

我不能完全确定是否有解决此问题的可行方法.据我了解,通过使用流,您可以有效地将迭代(及相关代码)委派给VM,从而将进程推入流本身的黑匣子中.

I'm not entirely certain there is a viable work around for this problem. By using streams you are effectively delegating iteration (and the associated code) to the VM as far as I understand it, thus shoving the process into a black box that is the stream itself.

至少从我所读到的关于它们的内容来看.对于我来说,这就是lambda代码发生的事情(如果它们足够复杂,则很难跟踪它们周围的情况).我对那里的任何调试选项都非常感兴趣,但是我个人还没有发现任何调试选项.

At least from what I've read about them. This is sort of what's happened around lambda code for me (if they're complex enough, it's very difficult to track what's happening around them). I'd be very interested in any debugging options out there, but I haven't personally found any.

这篇关于在Java 8流中使用交互式调试器的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆