考虑下面enums哪个更好?它们都可以完全相同的方式使用,但它们相互之间的优势是什么?
1.覆盖抽象方法:
public enum Direction {
UP {
@Override
public Direction getOppposite() {
return DOWN;
}
@Override
public Direction getRotateClockwise() {
return RIGHT;
}
@Override
public Direction getRotateAnticlockwise() {
return LEFT;
}
},
/* DOWN, LEFT and RIGHT skipped */
;
public abstract Direction getOppposite();
public abstract Direction getRotateClockwise();
public abstract Direction getRotateAnticlockwise();
}
Run Code Online (Sandbox Code Playgroud)
2.使用单一方法:
public enum Orientation {
UP, DOWN, LEFT, RIGHT;
public Orientation getOppposite() {
switch (this) {
case UP:
return DOWN;
case DOWN:
return UP;
case LEFT:
return RIGHT;
case RIGHT:
return LEFT;
default:
return null;
}
}
/* getRotateClockwise and getRotateAnticlockwise skipped */
}
Run Code Online (Sandbox Code Playgroud)
编辑:我真的希望看到一些很好的理由/精心解答的答案,以及特定声明的证据/来源.由于缺乏证据,大多数关于性能的现有答案并不真正令人信服.
您可以建议替代方案,但必须明确它是如何比所陈述的更好和/或所述方法更糟,并在需要时提供证据.
Pau*_*ora 21
忘记这个比较中的表现; 如果两种方法之间存在有意义的性能差异,那将需要一个真正庞大的枚举.
让我们关注可维护性.假设您完成了对Direction枚举的编码并最终转向更有声望的项目.与此同时,另一位开发人员获得了旧代码的所有权,包括Direction- 让我们称他为吉米.
在某些时候,要求要求吉米添加两个新方向:FORWARD和BACKWARD.吉米很累,工作过度,并没有费心去全面研究这会如何影响现有的功能 - 他就是这样做的.让我们看看现在发生了什么:
1.覆盖抽象方法:
Jimmy立即得到一个编译器错误(实际上他可能会在enum常量声明下面发现方法覆盖).在任何情况下,都会在编译时发现并修复问题.
2.使用单一方法:
Jimmy没有收到编译器错误,甚至没有得到IDE的错误切换警告,因为你switch已经有了一个default案例.稍后,在运行时,FORWARD.getOpposite()返回一段代码调用null.这会导致意外行为,并且最多会很快导致NullPointerException抛出.
让我们备份并假装你添加一些面向未来的代替:
default:
throw new UnsupportedOperationException("Unexpected Direction!");
Run Code Online (Sandbox Code Playgroud)
即便如此,直到运行时才会发现问题.希望该项目得到适当的测试!
现在,您的Direction示例非常简单,因此这种情况可能看起来有点夸张.但实际上,枚举可以像其他类一样容易地成为维护问题.在一个更大,更老的代码库中,有多个开发人员对重构的弹性是一个合理的问题.许多人谈论优化代码,但他们可以忘记开发时间也需要优化 - 包括编码以防止错误.
编辑:JLS示例§8.9.2-4下的注释似乎同意:
常量特定的类主体将行为附加到常量.[this]模式比使用
switch基类型中的语句更安全...因为模式排除了忘记为新常量添加行为的可能性(因为枚举声明会导致编译时错误).
| 归档时间: |
|
| 查看次数: |
2713 次 |
| 最近记录: |