Java 8中能否对Lambda表达式进行调试?

6

我刚刚开始尝试使用Java 8 Lambdas,但注意到在NetBeans IDE中无法对其进行调试。当我尝试在以下代码上设置断点时,出现了一个变量断点,这明显不是我想要的:

private EventListener myListener (Event event) ->
{
  command1;
  command2; // Set Breakpoint here
  command3;
};

NetBeans会在"myListener"变量上附加调试器,但我无法进入EventListener本身,因此我无法查看其内部发生的情况。
这是由于缺少调试信息、NetBeans中缺少该功能还是Java中不可能调试Lambda表达式?

只是确认一下,你是在使用Netbeans 8吗?Netbeans 7.4或许也支持Java 8。 - skiwi
1
是的,我正在使用NetBeans 8。 - mw88
3个回答

5

在Eclipse中,它对我有效。例如:

public class Foo {

    private static final Runnable r1 = () -> {
        System.out.println("r1a");
        System.out.println("r1b");
    };

    public static void main(String[] args) {
        Runnable r2 = () -> {
            System.out.println("r2a");
            System.out.println("r2b");
        };

        r1.run();
        r2.run();
    }
}

我可以在r1r2的每个行上添加断点,并且它们会适当地被触发,还可以进行步进等操作。
如果我只在run()调用上设置断点,我也可以进入相关的lambda表达式。
因此,所有调试信息至少都是可用的。
编辑:显然上述方法在Netbeans中也适用 - 我建议您尝试一下以检查您是否可以使其正常工作。

@JeroenVannevel:你是用strg+f8设置断点还是点击行号?使用strg+f8似乎可以,但使用行号却不行,这可能是一个bug,也可能是我的设置有问题... - mw88

3

使用以下示例代码在 Netbeans 8 Release 中:

private void init() {
    List<Map<Integer, String>> mapList = new ArrayList<>();

    Map<Integer, String> map1 = new HashMap<>();
    map1.put(1, "String1");
    mapList.add(map1);

    Map<Integer, String> map2 = new HashMap<>();
    map2.put(2, "String2");
    mapList.add(map2);

    Map<Integer, String> map3 = new HashMap<>();
    map3.put(1, "String3");
    mapList.add(map3);

    Map<Integer, String> map4 = new HashMap<>();
    map4.put(2, "String4");
    mapList.add(map4);

    Map<Integer, List<String>> response = mapList.stream()
            .flatMap(map -> map.entrySet().stream())
            .collect(
                    Collectors.groupingBy(
                            Map.Entry::getKey, 
                            Collectors.mapping(
                                    Map.Entry::getValue, 
                                    Collectors.toList()
                            )
                    )
            );
    response.forEach((i, l) -> {
        System.out.println("Integer: " + i + " / List: " + l);
    });
}

我可以在System.out.println("Integer: " + i + " / List: " + l);上设置断点,并且很好地检查了变量值(il)。

因此,我倾向于说它正在工作。


对我有用,谢谢你的回答。但是我和Jon Skeet的回答一样有同样的问题。 - mw88

2
在IntelliJ中,对我也起作用:
Stream.generate(() -> {
    return random.nextInt();
}).limit(10).count();

只有当我提供像 count() 这样的终止操作时,才能调试到返回值 random.nextInt()


2
只是为了你(和其他人)的信息,这段代码可以被写成new Random().ints(10)来生成一个IntStream,所以完整的代码可以是new Random().ints(10).count(),但我知道这样就不再有lambda表达式来捕获了。 - skiwi
对我来说没问题,谢谢你的回答。但是我和Jon Skeet的回答一样有同样的问题。 - mw88

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接