非法前向引用和枚举
我正在用java编写一个游戏,它由瓷砖网格组成。我不希望能够直观地定义图块的边缘以及它们彼此之间的关系,例如要获得图块的相对边缘,我希望能够仅键入 TOP.opposite()< /代码>。然而,当使用枚举来定义这些边时,我最终不得不在构造函数中转发至少其中两个边:
public enum Edge {
TOP(Edge.BOTTOM), //illegal forward reference
BOTTOM(Edge.TOP),
LEFT(Edge.RIGHT), //illegal forward reference
RIGHT(Edge.LEFT);
private Edge opposite;
private Edge(Edge opp){
this.opposite = opp;
}
public Edge opposite(){
return this.opposite;
}
}
是否有任何方法可以使用同样简单的枚举来解决这个问题?
I'm programming a game in java which is made up of a grid of tiles. I wan't to be able to inuitively define the edges of the tiles and how they relate to each other, e.g. to get the opposite edge of a tile, I want to be able to just type TOP.opposite()
. However, when using enums to define these edges I end up having to forward reference at least two of them in the contstructor:
public enum Edge {
TOP(Edge.BOTTOM), //illegal forward reference
BOTTOM(Edge.TOP),
LEFT(Edge.RIGHT), //illegal forward reference
RIGHT(Edge.LEFT);
private Edge opposite;
private Edge(Edge opp){
this.opposite = opp;
}
public Edge opposite(){
return this.opposite;
}
}
Is there any way of getting round this problem using enums which is just as simple?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
你可以这样做,但并不那么直观。
You can do this which is not as intuitive.
您还可以在枚举中使用静态内部类:
从 此处 :)
You can also make use of an static innerclass inside the enum:
Stolen from here :)
添加方法
opposite
以返回枚举对象您可以定义一个方法
opposite()
。在现代 Java 中,开关表达式
在现代 Java 中,我们可以使用 开关表达式。编译器确保我们涵盖了所有可能的情况。
用法:
在早期的 Java 中,
switch
在早期的 Java 中,使用以下代码中所示的语法。
请注意,需要使用
default
大小写,以防您向枚举添加元素或无意中从switch
中删除大小写。Add a method
opposite
to return enum objectYou could just define a method,
opposite()
.In modern Java, switch expression
In modern Java, we can use a switch expression. The compiler ensures that we have covered all possible cases.
Usage:
In earlier Java,
switch
In older Java, use syntax seen in the following code.
Notice the need for a
default
case, in case you ever add an element to the enum or you inadvertently delete a case from theswitch
.然而,
Peter Lawrey 的解决方案是另一种更高效且编译时安全的方法。
Here's another way
Peter Lawrey's solution is however more efficient and compiletime safe.
您可以创建一个静态
Map
,其中键是原始枚举,值是相对的边缘。在静态块中初始化它并从opposite()
方法返回映射。编辑:正如评论中建议的更好地使用EnumMap,所以我相应地升级了
。当您创建静态
fromString()
方法等时,这种方法通常很有用。You can create a static
Map
where key is the original enum and the value the opposite edge. Initialize it in a static block and the return the mapping from theopposite()
method.EDIT: as proposed in comment better to use EnumMap, so I upgraded accordingly
Btw. this approach is generally useful when you create something like static
fromString()
method etc.您可以使用内部映射来定义这些关联。如果在初始化映射时,您已经创建了所有枚举值,则此方法有效:
You could use an internal Map instead to define these associations. This works if at the point of initializing the Map, you already have all enum values created:
我的方法是使用序数。这是一个简单的示例,但对于更复杂的示例,请参见下文。
尽管不鼓励使用序数,因为它很脆弱,但在定义的同一枚举中使用序数则不那么脆弱,并且这里通过注释进一步缓解了这种情况。虽然上面的例子相当简单,但下一个例子就不那么简单了。比较原来的方式和使用序数的方式:
从 98 行:
到 19 行:
My method is by using ordinal. This is a simple example, but for a much more complex example see below.
Although using ordinal is discouraged for being fragile, using ordinal in the same enum as it's defined in is less fragile, and it's further mitigated here with a comment. Though the example above is quite trivial, the next example is less so. Compare the original way and the way using ordinal:
From 98 lines:
to 19 lines:
我更喜欢这个:
I preferred this:
使用 Java 8 lambda:
With Java 8 lambdas: