为什么要在 Java 中使用静态嵌套接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/71625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why would a static nested interface be used in Java?
提问by Mo.
I have just found a static nested interface in our code-base.
我刚刚在我们的代码库中发现了一个静态嵌套接口。
class Foo {
public static interface Bar {
/* snip */
}
/* snip */
}
I have never seen this before. The original developer is out of reach. Therefore I have to ask SO:
我以前从未见过这个。原始开发人员遥不可及。因此我不得不问SO:
What are the semantics behind a static interface? What would change, if I remove the static
? Why would anyone do this?
静态接口背后的语义是什么?如果我删除 ,会发生什么变化static
?为什么会有人这样做?
采纳答案by Jesse Glick
The static keyword in the above example is redundant (a nested interface is automatically "static") and can be removed with no effect on semantics; I would recommend it be removed. The same goes for "public" on interface methods and "public final" on interface fields - the modifiers are redundant and just add clutter to the source code.
上例中的 static 关键字是多余的(嵌套接口自动为“静态”),可以删除而不影响语义;我建议将其删除。接口方法上的“public”和接口字段上的“public final”也是如此——修饰符是多余的,只会给源代码添加混乱。
Either way, the developer is simply declaring an interface named Foo.Bar. There is no further association with the enclosing class, except that code which cannot access Foo will not be able to access Foo.Bar either. (From source code - bytecode or reflection can access Foo.Bar even if Foo is package-private!)
无论哪种方式,开发人员都只是声明了一个名为 Foo.Bar 的接口。除了无法访问 Foo 的代码也无法访问 Foo.Bar 之外,与封闭类没有进一步的关联。(来自源代码 - 即使 Foo 是包私有的,字节码或反射也可以访问 Foo.Bar!)
It is acceptable style to create a nested interface this way if you expect it to be used only from the outer class, so that you do not create a new top-level name. For example:
如果您希望它仅在外部类中使用,那么以这种方式创建嵌套接口是可以接受的样式,这样您就不会创建新的顶级名称。例如:
public class Foo {
public interface Bar {
void callback();
}
public static void registerCallback(Bar bar) {...}
}
// ...elsewhere...
Foo.registerCallback(new Foo.Bar() {
public void callback() {...}
});
回答by Clinton N. Dreisbach
An inner interface has to be static in order to be accessed. The interface isn't associated with instances of the class, but with the class itself, so it would be accessed with Foo.Bar
, like so:
内部接口必须是静态的才能被访问。该接口不与类的实例相关联,而是与类本身相关联,因此可以使用 访问它Foo.Bar
,如下所示:
public class Baz implements Foo.Bar {
...
}
In most ways, this isn't different from a static inner class.
在大多数情况下,这与静态内部类没有什么不同。
回答by Henry B
To answer your question very directly, look at Map.Entry.
要非常直接地回答您的问题,请查看 Map.Entry。
also this may be useful
这也可能有用
回答by basszero
Typically I see static inner classes. Static inner classes cannot reference the containing classes wherease non-static classes can. Unless you're running into some package collisions (there already is an interface called Bar in the same package as Foo) I think I'd make it it's own file. It could also be a design decision to enforce the logical connection between Foo and Bar. Perhaps the author intended Bar to only be used with Foo (though a static inner interface won't enforce this, just a logical connection)
通常我会看到静态内部类。静态内部类不能引用包含类,而非静态类可以。除非你遇到一些包冲突(在与 Foo 相同的包中已经有一个名为 Bar 的接口),我想我会把它作为自己的文件。强制执行 Foo 和 Bar 之间的逻辑连接也可能是一个设计决策。也许作者打算将 Bar 仅与 Foo 一起使用(尽管静态内部接口不会强制执行此操作,只是逻辑连接)
回答by Vordreller
Static means that any class part of the package(project) can acces it without using a pointer. This can be usefull or hindering depending on the situation.
静态意味着包(项目)的任何类部分都可以在不使用指针的情况下访问它。根据情况,这可能是有用的,也可能是阻碍。
The perfect example of the usefullnes of "static" methods is the Math class. All methods in Math are static. This means you don't have to go out of your way, make a new instance, declare variables and store them in even more variables, you can just enter your data and get a result.
“静态”方法有用的完美例子是 Math 类。Math 中的所有方法都是静态的。这意味着您不必特意创建一个新实例,声明变量并将它们存储在更多变量中,您只需输入数据即可获得结果。
Static isn't always that usefull. If you're doing case-comparison for instance, you might want to store data in several different ways. You can't create three static methods with identical signatures. You need 3 different instances, non-static, and then you can and compare, caus if it's static, the data won't change along with the input.
静态并不总是那么有用。例如,如果您要进行案例比较,您可能希望以几种不同的方式存储数据。您不能创建三个具有相同签名的静态方法。您需要 3 个不同的实例,非静态的,然后您可以进行比较,因为如果它是静态的,则数据不会随着输入而改变。
Static methods are good for one-time returns and quick calculations or easy obtained data.
静态方法适用于一次性返回和快速计算或容易获得的数据。
回答by Skizz
In Java, the static interface/class allows the interface/class to be used like a top-level class, that is, it can be declared by other classes. So, you can do:
在Java中,静态接口/类允许接口/类像顶级类一样使用,即可以被其他类声明。所以,你可以这样做:
class Bob
{
void FuncA ()
{
Foo.Bar foobar;
}
}
Without the static, the above would fail to compile. The advantage to this is that you don't need a new source file just to declare the interface. It also visually associates the interface Bar to the class Foo since you have to write Foo.Bar and implies that the Foo class does something with instances of Foo.Bar.
如果没有静态,上述内容将无法编译。这样做的好处是您不需要新的源文件来声明接口。它还在视觉上将接口 Bar 与类 Foo 相关联,因为您必须编写 Foo.Bar 并暗示 Foo 类对 Foo.Bar 的实例执行某些操作。
回答by Bas Leijdekkers
Member interfaces are implicitly static. The static modifier in your example can be removed without changing the semantics of the code. See also the the Java Language Specification 8.5.1. Static Member Type Declarations
成员接口是隐式静态的。可以在不更改代码语义的情况下删除示例中的 static 修饰符。另请参阅 Java 语言规范8.5.1。静态成员类型声明
回答by ColinD
The question has been answered, but one good reason to use a nested interface is if its function is directly related to the class it is in. A good example of this is a Listener
. If you had a class Foo
and you wanted other classes to be able to listen for events on it, you could declare an interface named FooListener
, which is ok, but it would probably be more clear to declare a nested interface and have those other classes implement Foo.Listener
(a nested class Foo.Event
isn't bad along with this).
这个问题已经回答了,但是使用嵌套接口的一个很好的理由是它的功能是否与它所在的类直接相关。一个很好的例子是Listener
. 如果您有一个类Foo
并且您希望其他类能够侦听其上的事件,则可以声明一个名为 的接口FooListener
,这没问题,但是声明一个嵌套接口并让其他类实现Foo.Listener
(嵌套类Foo.Event
也不错)。
回答by user1982892
Jesse's answer is close, but I think that there is a better code to demonstrate why an inner interface may be useful. Look at the code below before you read on. Can you find why the inner interface is useful? The answer is that class DoSomethingAlready can be instantiated with anyclass that implements A and C; not just the concrete class Zoo. Of course, this can be achieved even if AC is not inner, but imagine concatenating longer names (not just A and C), and doing this for other combinations (say, A and B, C and B, etc.) and you easily see how things go out of control. Not to mention that people reviewing your source tree will be overwhelmed by interfaces that are meaningful only in one class.So to summarize, an inner interface enables the construction of custom types and improves their encapsulation.
Jesse 的回答很接近,但我认为有更好的代码来演示为什么内部接口可能有用。在继续阅读之前,请先查看下面的代码。你能找到为什么内部接口有用吗?答案是 DoSomethingAlready 类可以用任何实现 A 和 C 的类来实例化;不仅仅是具体的类 Zoo。当然,即使 AC 不是内部的,也可以实现这一点,但是想象一下连接更长的名称(不仅仅是 A 和 C),并为其他组合(例如 A 和 B、C 和 B 等)执行此操作,并且您很容易看看事情是如何失控的。更不用说你的源代码树的人会被那些只在一个类中有意义的接口所淹没。所以总结一下,内部接口允许构建自定义类型并改进它们的封装。
class ConcreteA implements A {
:
}
class ConcreteB implements B {
:
}
class ConcreteC implements C {
:
}
class Zoo implements A, C {
:
}
class DoSomethingAlready {
interface AC extends A, C { }
private final AC ac;
DoSomethingAlready(AC ac) {
this.ac = ac;
}
}
回答by Danylo Volokh
If you will change class Foo into interface Foo the "public" keyword in the above example will be also redundant as well because
如果您将类 Foo 更改为接口 Foo,则上述示例中的“public”关键字也将是多余的,因为
interface defined inside another interface will implicitly public static.
在另一个接口内定义的接口将隐式公开静态。