为什么在Java中使用静态嵌套接口?

问题

我刚刚在代码库中找到了一个静态嵌套接口。

class Foo {
    public static interface Bar {
        /* snip */
    }
    /* snip */
}

我以前从未见过这个。最初的开发者是遥不可及的。所以我要问:

静态接口背后的语义是什么?如果我删除static会有什么变化?为什么有人会这样做?


#1 热门回答(282 赞)

上例中的static关键字是冗余的(嵌套接口自动为"静态"),可以删除而不会影响语义;我建议将其删除。接口方法上的"public"和接口字段上的"public final"也是如此 - 修饰符是冗余的,只是为源代码添加了混乱。

无论哪种方式,开发人员只是声明一个名为Foo.Bar的接口。除了无法访问Foo的代码也无法访问Foo.Bar之外,没有与封闭类的进一步关联。 (从源代码 - 字节码或反射可以访问Foo.Bar,即使Foo是包私有的!)

如果你希望仅从外部类使用嵌套接口,则以这种方式创建嵌套接口是可接受的样式,这样你就不会创建新的顶级名称。例如:

public class Foo {
    public interface Bar {
        void callback();
    }
    public static void registerCallback(Bar bar) {...}
}
// ...elsewhere...
Foo.registerCallback(new Foo.Bar() {
    public void callback() {...}
});

#2 热门回答(69 赞)

这个问题已得到解答,但是使用嵌套接口的一个很好的理由是它的函数与它所在的类直接相关。一个很好的例子是aListener。如果你有你想要其他类能够侦听其事件classFooand,你可以声明接口namedFooListener,这是确定的,但它可能会更清楚地声明嵌套接口,并具有与其他类implementFoo.Listener(一嵌套的classFoo.Event并不坏于此)。


#3 热门回答(13 赞)

成员接口是隐式静态的。可以删除示例中的static修饰符,而无需更改代码的语义。另请参阅Java语言规范8.5.1. Static Member Type Declarations