从内部类到外部接口的非静态访问的基本障碍

2022-09-04 04:00:21

例:

interface Outer {
    default String get() {
        return "hi";
    }
    class Inner {
        String got() {
            return get();
        }
    }
}

这会产生错误

java:非静态方法 get() 不能从静态上下文中引用。

内部接口/类始终是静态的;与外部类不同,在外部类中,除非声明为静态,否则它是非静态的。

这就是今天和即将到来的java 8的情况。外部类和外部接口之间的这种差异是否有根本原因?

更新:阅读@Radiodef的评论后,我将内部接口更改为内部类。外部类不能包含非静态内部接口,因此该示例令人困惑。无论如何,内部类确实是我想要的。

更新:仅供参考。这是完全合法的:

class Outer {
    String get() {
        return "hei";
    }
    class Inner {
        String got() {
            return get();
        }
    }
}

答案 1

也许我误解了你的问题,但你的代码片段完全等同于

interface Outer {
    public default String get() {
        return "hi";
    }
    public static class Inner {
        String got() {
            return get();
        }
    }
}

JLS 第 9.5 章(Java 8)所述

接口中的成员类型声明隐式为 和 。允许冗余指定这些修饰符中的一个或两个。publicstatic

所以如果你做了

Inner innerInstance = new Outer.Inner();
innerInstance.got();

什么将被调用?此处不涉及任何类型的对象。get()Outer

外部类和外部接口之间的这种差异是否有根本原因?

这不是问题所在。您的类代码是内部类的一个示例,即。非嵌套类。接口代码是静态嵌套类的一个示例。你正在比较两个不同的东西。static

在封闭类中具有嵌套类的等效示例是static

class Outer {
    String get() {
        return "hei";
    }

    public static class Inner {
        String got() {
            return get(); // won't compile
        }
    }
}

同样,它不起作用,因为没有相应的(封闭)实例来调用它。get()


如果问题,如@Radiodef所说,是

为什么类必须是隐式静态的,而不是这是现有的规范?

那么我的答案如下:

根据定义,接口是

独立系统或不同群体相互作用的点

接口没有状态,也没有行为。它只是描述行为。接口成员是隐式的,因为接口没有状态。static


答案 2

我会为你提供一种记住它的方法。

  1. 对于成员,它不绑定到声明类/接口的对象;对于非成员,它必须绑定到声明类的对象。staticstatic
  2. 所有接口的成员都是隐式的,除了一个。staticdefault

所以,在你的Example中:不绑定到的对象(因为接口的对象没有意义),所以它不能调用的成员。static class Innerinterface OuterOuter

对于您在 Update: 中的合法对象绑定到 ,因此当您创建 的对象时,您还创建了 一个 匿名对象 ,因此当您调用 时,将调用该匿名对象。class Innerclass OuterInnerclass Outerget()Inner::got()get()

希望这有帮助。


推荐