我有以下领域在我的代码:什么时候应该使用final关键字而不是枚举?
private static final int NUM_NANOSECONDS_IN_MILLISECOND = 1000000;
有人告诉我,我应该使用枚举这种类型的安全性。这不是我熟悉的。但是,如果是这样的话,我不知道什么时候在字段上使用final关键字是合适的。
什么时候应该使用final关键字而不是枚举?
我有以下领域在我的代码:什么时候应该使用final关键字而不是枚举?
private static final int NUM_NANOSECONDS_IN_MILLISECOND = 1000000;
有人告诉我,我应该使用枚举这种类型的安全性。这不是我熟悉的。但是,如果是这样的话,我不知道什么时候在字段上使用final关键字是合适的。
什么时候应该使用final关键字而不是枚举?
常量就是这样,常量名称。枚举是具有值的文字常量。我解释...
考虑:
public final static int NORTH = 0;
public final static int SOUTH = 1;
public final static int EAST = 2;
public final static int WEST = 3;
和
public enum Direction {
NORTH, SOUTH, EAST, WEST
}
从可读性的角度来看它还挺看起来是一样的:
if(direction == NORTH)
或枚举:
if(direction == Direction.NORTH)
如果事情可能出错是与最后的常数,你也可以做
if(direction == 0)
现在是更难理解,即使它做同样的事情的代码。有了枚举,你就不能这样做,所以它让问题。
同样,期待一个方向作为方法的参数时:
与最终静态:
public void myMethod(int direction)
,并用枚举:对问题
public void myMethod(Direction direction)
它更清晰,少的机会。
这只是一个开始。实际上,枚举实际上可以有方法帮助您更好地管理它们包含的信息。请阅读here以获取干净的说明。
例子:
public enum Direction {
NORTH (0, 1),
SOUTH (0, -1),
EAST (1, 0),
WEST (-1, 0)
private int xDirection, yDirection;
Direction(int x, int y) {
this.xDirection = x;
this.yDirection = y;
}
public Vector2D getTranslation() {
return new Vector2D(this.xDirection, this.yDirection);
}
}
这样,就要在你的代码:
public void moveThePlayer(Player p, Direction d) {
p.translate(d.getTranslation());
}
moveThePlayer(p, Direction.NORTH);
这成为真的很难做final static
。或者至少,它变得非常不可读。
所有这一切都被说明了,你正在使用的特定情况下,如果只有一个数字常量值,我会保持最终的静态。如果存在单个值,则不需要使用枚举。
嘿,这是翻译的一种奇特的方式。 – EpicPandaForce
就是我写的那样,以说明这一点,我认为它很好。 – mprivat
使用枚举避免使用int
而不是final
。使用专用的枚举提供了类型安全性,因此您可以拥有更清晰的方法签名并避免错误。 final
用于防止一旦设置就更改值,并且无论变量的类型如何,都是一种很好的实践。
在这种情况下,但我不确定枚举给你什么价值。 NUM_NANOSECONDS_IN_MILLISECOND
似乎不应该是一个专用的类型,正如@BoristheSpider所说,你根本不需要这个字段。也许你的同事建议使用单位的枚举(例如NANOSECOND
,MILLISECOND
等),而不是像这样存储比率。在这种情况下,现有的TimeUnit
枚举肯定是你的朋友。
我会说,枚举的一般用例是当你有一个有限的一组有限的值,它们构成你正在建模的一些集合,并且你将枚举每一个。它们还可以帮助确保包含这些值之一的字段不包含其他值。
在这种情况下,似乎都不适用。你也可以有NUM_NANOSECONDS_IN_MICROSECOND
,NUM_NANOSECONDS_IN_SECOND
,NUM_NANOSECONDS_IN_PI_MILLISECONDS
等等,你不打算列举每一个。此外,您似乎将要存储这些值的变量似乎不应该限制为定义的常量的值。
它诚实地取决于你需要什么。 enum
正如其名称所示代表枚举。
枚举有多个元素,像这样
public enum Colors {
CYAN, MAGENTA, YELLOW, BLACK
}
你甚至可以给他们的数值左右!因为枚举很酷。
public enum RGBColors {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
private int hexacolor;
private RGBColors(int hexacolor) {
this.hexacolor = hexacolor;
}
public int getColorValue() {
return hexacolor;
}
}
你的情况只是一个数值常量。 A 单数数值常数。
public static final long SUCH_NUMERICAL_VALUE = 12367160L;
这只是一个常数。这不是枚举。也没有理由将它作为枚举,因为您只是将它用作数字。
enum
最大的优点(在我看来)是,你可以迭代它的类型的每个元素。
for(RGBColors rgbColor : RGBColors.values()) {
... //do things with rgbColor for each of them
}
你不能这样做与public static final int
。我甚至写了一个enum
包装周围一堆public static final
性能在这里是因为这个问题的:https://stackoverflow.com/a/28295134/2413303
更重要的是,你可以轻松地阅读代表什么价值的东西,而不必深入到源:
RGBColors red = RGBColors.RED;
现在让我们看看这个与诠释:
int red = RGBColors.RED;
我只能说
int red = 0; //red color
谁会知道后来到底是什么?谁知道!
不管怎么说,简单的答案是,枚举是伟大的,当你指定枚举,又名多个元素(或你正在创建枚举单身),而这些要素需要有额外的方法或属性。 常数:当您使用它们作为正是
public enum MySingleton { //this is an enum singleton
INSTANCE;
public void doThings() {
System.out.println("hello!");
}
}
MySingleton.INSTANCE.doThings(); //hello!
常数(public static final
)是巨大的。
在编写源代码时,最好尽可能依靠编译器来帮助您查找逻辑错误。一种方法是使用变量和常量类型,这样如果对方法使用错误常量,编译器会将其标记为错误。
该建议并非真正使用final
与enum
,因为这些实际上是两种不同的编程概念。相反,使用enum
创建一个明确且唯一的类型,而不是使用明确且唯一的int
。如果您使用int
作为函数的方法签名的一部分,该函数应该需要几纳秒,那么编译器将接受任何int
值。如果您改为使用enum
,那么只允许在enum
中指定的那些值。使用其他任何东西都会导致编译器发出错误。
final
关键字是一种确保变量不能被覆盖或修改的方式,以便变量像常量一样工作。 wikipedia article on final。
在enum
指定的值是常量,因此您可以这样只有指定的使用你所拥有的,恒定的,或使用enum
,恒定之间进行选择,但是使用enum
将提供从编译器安全检查enum
的值可以在方法调用或变量赋值中用于纳秒。
这是一个来自该堆栈溢出的explanation of final
with additional links。 Java method keyword final and its use也提供了一些额外的信息。
有关enum
的一些说明,请参阅What is the purpose of Enum。
这种情况不一定是'enum',但是使用'int'和'enum'之间的决定是有意设计的。我会建议实现这个最简单,更可读的方式,你找到它。如果这一点在后来演变并需要改变,那么改变它,而不是现在。 –
为什么在这种情况下枚举更有意义?你从字面上看有一个价值,而不是几个。它也取决于使用情况;如果您正在为其添加值,则可以考虑在枚举之前添加更多常量。 – Makoto
谁告诉你的?不管它是谁,都要求他们解释并编辑你的问题和解释,因为我不知道他们在说什么。这听起来像是一个更适合C/C++的评论。 – ajb