私有接口方法的方法引用

2024-02-28

考虑以下代码:

public class A {
    public static void main(String[] args) {
        Runnable test1 = ((I)(new I() {}))::test;  // compiles OK
        Runnable test2 = ((new I() {}))::test;     // won't compile 
    }

    interface I {
        private void test() {}
    }
}

我不太明白这个意思。。我明白test()方法是private。但是如果我们将匿名类强制转换为其接口,会发生什么变化((I)(new I() {}))?更准确地说,我希望看到一个特定的 JLS 点可以实现该技巧。

P.S.我已将其报告为编译器错误(ID:9052217)。在我看来,这Runnable test2 = ((new I() {}))::test;在这种特殊情况下应该可以很好地编译。

P.P.S.到目前为止,根据我的报告创建了一个错误:https://bugs.openjdk.java.net/browse/JDK-8194998 https://bugs.openjdk.java.net/browse/JDK-8194998。它可能会因“无法修复”或其他原因而关闭。


这不是一个新问题,与私有接口方法或方法引用无关。

如果您更改代码来扩展类而不是实现接口,并调用该方法而不是引用它,您仍然会遇到完全相同的问题。

class A {
    public static void main(String[] args) {
        ((I)(new I() {})).test();  // compiles OK
        ((new I() {})).test();     // won't compile 
    }

    class I {
        private void test() {}
    }
}

不过,该代码可以应用于较旧的 Java 版本,我尝试了 Java 9、8、7、6、5 和 1.4。大家的行为都一样!!

The issue is that private methods are not inherited1, so the anonymous class doesn't have the method, at all. Since the private method doesn't even exist in the anonymous class, it cannot be called.

当你投射到I,该方法现在存在供编译器查看,并且因为I是一个内部类,您被授予访问权限(通过合成方法),即使它是私有的。

在我看来,这不是一个错误。这就是私有方法在继承上下文中的工作方式。

1) As found by Jorn Vernee https://stackoverflow.com/a/48215886/5221149 in JLS 6.6-5 https://docs.oracle.com/javase/specs/jls/se9/html/jls-6.html#d5e9799: "[A private class member] is not inherited by subclasses".

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

私有接口方法的方法引用 的相关文章

随机推荐