8

我在 IntelliJ IDEA 中编码。在调试我的应用程序时,我不能在Watches中使用一些默认方法实现。

这是一个精简的例子:

public class Friendship {
    interface Friend {
        default void sayHiTo(Friend friend) {
            System.out.println("Hi, " + friend.hashCode());
        }

        default int amountOfHands() {
            return 2;
        }
    }

    public static class BasicFriend implements Friend {

        int numberOfFaces() {
            return 1;
        }
    }

    public static void main(String[] args) {
        System.out.println("Put a breakpoint here");
    }
}

main()方法中,我设置了一个断点并设置了三个手表:

// Default interface method with dependency
new BasicFriend().sayHiTo(new BasicFriend())

// Default interface method without dependency
new BasicFriend().amountOfHands()

// Class method
new BasicFriend().numberOfFaces()

第一个手表抛出NoSuchMethodException抱怨该方法Friendship$BasicFriend.sayHiTo()不存在。

第二个手表成功运行,但奇怪的是它报告了一个装箱的对象 {java.lang.Integer@537} "2",而不仅仅是一个原始的2

正如预期的那样,第三个手表报告了一个原始 1。

为什么第一只手表不工作?这是一个错误吗?这实际上与IDE有关吗?是因为默认方法的一些概念缺陷吗?它应该首先按照我的意愿工作吗?第二只手表的奇怪结果与第一只手表的问题有某种关系吗?

4

1 回答 1

8

在 JDK 8u40 之前,JDI(Java 调试器接口)、JDWP(Java 调试器连线协议)和 JDB(标准 Java 调试器)不支持默认和静态接口方法。这是错误 JDK-8042123,它在 8u40 中被记录为已修复,并且相应的简介出现在8u40 发行说明中。

更新到 8u40 或更高版本以解决此问题,至少在 JDK 方面。

从错误描述来看,似乎还需要调试器端的更改,以避免将 com.sun.jdi.InterfaceType 对象转换为 com.sun.jdi.ClassType,而是直接调用 InterfaceType.invokeMethod()。

在 IntelliJ 的特定情况下,Suseika 在评论中确认14.1.2 已基本解决了该问题(除了意外的装箱),尽管Mike Kobit在该版本上仍然遇到此问题,并出现 ClassCastException 提示上述错误转换。

于 2015-05-04T19:28:48.253 回答