Java调试器无法调用某些默认方法实现 [英] Java debugger can't call some default method implementations

查看:152
本文介绍了Java调试器无法调用某些默认方法实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是一个简明示例:

  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() / code>方法我放一个断点并设置三个手表:

  //依赖关系的
new BasicFriend()。sayHiTo(new BasicFriend())

//默认接口方法,不依赖
new BasicFriend()。amountOfHands()

/ / Class方法
new BasicFriend()。numberOfFaces()

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



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



第三个手表报告一个原始1,就像预期一样。



为什么第一个手表不工作?这是一个bug吗?这是否与IDE相关?是因为默认方法有一些概念上的缺陷?应该按照我想要的方式工作吗?第二手表的奇怪结果与第一手表的问题有关吗?

解决方案

在JDK 8u40之前,默认和JDI(Java Debugger Interface),JDWP(Java Debugger Wire Protocol)和JDB(标准Java调试器)不支持静态接口方法。这是错误JDK-8042123 ,其记录为固定在8u40和相应的blurb出现在 8u40发行说明中。



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



从错误描述中看起来像调试器方面的更改也是必需的,以避免将com.sun.jdi.InterfaceType对象转换为com.sun.jdi.ClassType,而是直接调用InterfaceType.invokeMethod()。



在IntelliJ的具体情况下, Suseika在评论中确认,14.1.2主要修复了问题(除了意外的拳击),尽管 Mike Kobit仍然遇到这个问题,在该版本上,ClassCastException提示上面的错误的转换。 p>

I'm coding in IntelliJ IDEA. When debugging my application, I can't use some default method implementations in Watches.

Here is a condensed example:

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");
    }
}

In main() method I put a breakpoint and set up three watches:

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

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

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

The first watch throws NoSuchMethodException complaining that method Friendship$BasicFriend.sayHiTo() doesn't exist.

The second watch runs successfully, but strangely it reports a boxed object {java.lang.Integer@537} "2" instead of just a primitive 2.

The third watch reports a primitive 1, just as expected.

Why is the first watch not working? Is this a bug? Is this actually IDE related? Is it because of some conceptual flaw of default methods? Should it be working as I want it to in the first place? Is the strange result of the second watch somehow related to the issue in the first watch?

解决方案

Prior to JDK 8u40, default and static interface methods were not supported by JDI (Java Debugger Interface), JDWP (Java Debugger Wire Protocol) and JDB (the standard Java debugger). This is bug JDK-8042123, which is recorded as fixed in 8u40 and a corresponding blurb appears in the 8u40 release notes.

Update to 8u40 or later to fix this issue, at least on the JDK side.

From the bug description, it looks like debugger-side changes are also required, to avoid casting com.sun.jdi.InterfaceType objects to com.sun.jdi.ClassType, but instead call InterfaceType.invokeMethod() directly.

In the specific case of IntelliJ, Suseika confirmed in a comment that 14.1.2 has mostly fixed the issue (except the unexpected boxing), though Mike Kobit still experiences this problem on that version with a ClassCastException suggestive of the incorrect cast above.

这篇关于Java调试器无法调用某些默认方法实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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