我对C#非常熟悉,但开始在Java中工作更多.我希望得知Java中的枚举基本上与C#中的枚举相同,但显然情况并非如此.最初,我很高兴得知Java枚举可能包含多个数据,这似乎非常有利(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html).但是,从那时起我发现C#中缺少许多功能,例如能够轻松地为枚举元素分配特定值,以及因此无需花费大量精力就能将整数转换为枚举(即整数值转换为相匹配的Java枚举).
所以我的问题是:对于带有一堆公共静态最终字段的类,Java枚举是否有任何好处?或者它只提供更紧凑的语法?
编辑:让我更清楚.Java枚举对于具有相同类型的一组公共静态最终字段的类有什么好处?例如,在第一个链接的行星示例中,枚举对具有这些公共常量的类有什么好处:
public static final Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
public static final Planet VENUS = new Planet(4.869e+24, 6.0518e6);
public static final Planet EARTH = new Planet(5.976e+24, 6.37814e6);
public static final Planet MARS = new Planet(6.421e+23, 3.3972e6);
public static final Planet JUPITER = new Planet(1.9e+27, 7.1492e7);
public static final Planet SATURN = new Planet(5.688e+26, 6.0268e7);
public static final Planet URANUS = new Planet(8.686e+25, 2.5559e7);
public static final Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);
Run Code Online (Sandbox Code Playgroud)
据我所知,卡萨布兰卡的答案是唯一能满足这一要求的人.
use*_*421 94
switch
语句中使用值case
.ordinal().
EnumSet
和EnumMap
课程.cas*_*nca 76
从技术上讲,人们确实可以将枚举视为一个带有一堆类型常量的类,这实际上是如何在内部实现枚举常量.enum
然而,使用a 为您提供了有用的方法(Enum javadoc),否则您必须自己实现,例如Enum.valueOf
.
Dav*_*ton 73
没有人提到在switch
陈述中使用它们的能力; 我也会把它扔进去.
这允许以干净的方式使用任意复杂的枚举,而不使用instanceof
可能混淆的if
序列或非字符串/ int切换值.规范示例是状态机.
Jim*_*son 42
主要优点是类型安全.使用一组常量,可以使用相同内在类型的任何值,从而引入错误.使用枚举时,只能使用适用的值.
例如
public static final int SIZE_SMALL = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE = 3;
public void setSize(int newSize) { ... }
obj.setSize(15); // Compiles but likely to fail later
Run Code Online (Sandbox Code Playgroud)
VS
public enum Size { SMALL, MEDIUM, LARGE };
public void setSize(Size s) { ... }
obj.setSize( ? ); // Can't even express the above example with an enum
Run Code Online (Sandbox Code Playgroud)
Jef*_*rey 42
混淆少了.举个Font
例子.它有一个构造函数,它带有Font
你想要的名称,它的大小和样式(new Font(String, int, int)
).直到今天,我还记不起风格或尺寸是否先行.如果Font
已经使用了enum
其所有不同的风格(PLAIN
,BOLD
,ITALIC
,BOLD_ITALIC
),它的构造看起来像Font(String, Style, int)
,防止任何混乱.不幸的是,在创建类enum
时,s并不存在Font
,并且由于Java必须保持反向兼容性,因此我们总是会被这种模糊性所困扰.
当然,这只是使用enum
而不是public static final
常量的论据.枚举也非常适合单身人士和实现默认行为,同时允许以后的自定义(IE 策略模式).后者的一个例子是java.nio.file
的OpenOption
和StandardOpenOption
:如果开发者想创造自己的不规范OpenOption
,他可能.
icz*_*cza 25
这里有很多好的答案,但都没有提到专门针对枚举的Collection API类/接口的高度优化实现:
这些枚举特定类只接受Enum
实例(EnumMap
唯一的接受Enum
只作为键),并且只要有可能,它们在其实现中恢复为紧凑表示和位操作.
这是什么意思?
如果我们的Enum
类型不再有64个元素(大多数现实Enum
例子都符合这个要求),那么实现将元素存储在一个long
值中,每个Enum
有问题的实例将与这个64位长的一些相关联long
.向a添加元素EnumSet
只是将正确的位设置为1,删除它只是将该位设置为0.测试元素Set
是否只是一个位掩码测试!现在你必须Enum
为此而爱!
小智 12
例:
public class CurrencyDenom {
public static final int PENNY = 1;
public static final int NICKLE = 5;
public static final int DIME = 10;
public static final int QUARTER = 25;}
Run Code Online (Sandbox Code Playgroud)
java常量的限制
1)没有类型安全:首先它不是类型安全的; 您可以将任何有效的int值分配给int,例如99,尽管没有硬币来表示该值.
2)无意义打印:任何这些常量的打印值将打印其数值而不是有意义的硬币名称,例如,当您打印NICKLE时,它将打印"5"而不是"NICKLE"
3)没有命名空间:要访问currencyDenom常量我们需要为类名添加前缀,例如CurrencyDenom.PENNY而不是仅使用PENNY,尽管这也可以通过在JDK 1.5中使用静态导入来实现
枚举的优点
1)Java中的枚举是类型安全的,并且有自己的名称空间.这意味着您的枚举将在下面的示例中具有类型"货币"的类型,并且您不能分配除枚举常量中指定的值之外的任何值.
public enum Currency {PENNY, NICKLE, DIME, QUARTER};
Run Code Online (Sandbox Code Playgroud)
Currency coin = Currency.PENNY;
coin = 1; //compilation error
2)Java中的Enum是类或接口的引用类型,您可以在java Enum中定义构造函数,方法和变量,这使得它在C和C++中比Enum更强大,如下一个Java Enum类型示例所示.
3)您可以在创建时指定枚举常量的值,如下例所示:public enum Currency {PENNY(1),NICKLE(5),DIME(10),QUARTER(25)}; 但是要实现这一点,你需要定义一个成员变量和一个构造函数,因为PENNY(1)实际上是在调用一个接受int值的构造函数,见下面的例子.
public enum Currency {
PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
private int value;
private Currency(int value) {
this.value = value;
}
};
Run Code Online (Sandbox Code Playgroud)
参考:https://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html
小智 11
正如您已经注意到的,枚举的第一个好处是语法简单.但是枚举的主要目的是提供一组众所周知的常量,默认情况下,这些常量形成一个范围,并通过类型和值安全检查帮助执行更全面的代码分析.
枚举的这些属性有助于程序员和编译器.例如,假设您看到一个接受整数的函数.整数意味着什么?你能传递什么样的价值观?你真的不知道.但是如果你看到一个接受枚举的函数,你就会非常清楚所有可以传入的值.
对于编译器,枚举有助于确定一系列值,除非您为枚举成员指定特殊值,否则它们的范围从0到更高.这有助于通过类型安全检查等自动跟踪代码中的错误.例如,编译器可能会警告您在switch语句中没有处理所有可能的枚举值(即,当您没有default
case并且只处理N个enum值中的一个时).当你将任意整数转换为枚举时,它也会发出警告,因为枚举的值范围小于整数,而这反过来可能会触发函数中不会真正接受整数的错误.此外,当值从0开始时,为开关生成跳转表变得更容易.
这不仅适用于Java,也适用于具有严格类型检查的其他语言.C,C++,D,C#就是很好的例子.
枚举的好处:
“例如能够轻松地为枚举元素分配某个值”
enum EnumX{
VAL_1(1),
VAL_200(200);
public final int certainValue;
private X(int certainValue){this.certainValue = certainValue;}
}
Run Code Online (Sandbox Code Playgroud)
“因此无需付出很大的努力就能将整数转换为枚举” Add a method converting int to enum which does that. Just add static HashMap<Integer, EnumX> containing the mapping.
如果您确实想将 ord=VAL_200.ordinal() 转换回 val_200,只需使用: EnumX.values()[ord]
枚举是隐式最终的,具有私有构造函数,其所有值都是相同类型或子类型,您可以使用values()
获取其所有值,获取其name()
或ordinal()
值,或者您可以按数字或名称查找枚举。
您还可以定义子类(即使名义上是最终的,但您不能以任何其他方式做)
enum Runner implements Runnable {
HI {
public void run() {
System.out.println("Hello");
}
}, BYE {
public void run() {
System.out.println("Sayonara");
}
public String toString() {
return "good-bye";
}
}
}
class MYRunner extends Runner // won't compile.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
108500 次 |
最近记录: |