Java 枚举(或 int 常量)与 c 枚举
Java enum (or int constants) vs c enum
我正在尝试做一些在 C:
中通常看起来像这样的事情
typedef enum {
HTTP =80,
TELNET=23,
SMTP =25,
SSH =22,
GOPHER=70} TcpPort;
方法一
这是我在 Java 中的内容,使用 enum
:
public static enum TcpPort{
HTTP(80),
TELNET(23),
SMTP(25),
SSH(22),
GOPHER(70);
private static final HashMap<Integer,TcpPort> portsByNumber;
static{
portsByNumber = new HashMap<Integer,TcpPort>();
for(TcpPort port : TcpPort.values()){
portsByNumber.put(port.getValue(),port);
}
}
private final int value;
TcpPort(int value){
this.value = value;
}
public int getValue(){
return value;
}
public static TcpPort getForValue(int value){
return portsByNumber.get(value);
}
}
方法 1 - 问题
我发现我不得不在不同的地方重复这个模式,但我想知道:有没有更好的方法?特别是因为:
- 这看起来很复杂而且不够优雅,
- 它还将编译时间转移到 运行 时间。
我使用此映射的原因之一是因为它在 switch 语句中看起来更好,例如:
switch(tcpPort){
case HTTP:
doHttpStuff();
break;
case TELNET:
doTelnetStuff();
break;
....
}
我想枚举也有更强的类型安全性的好处。
方法二
我知道我可以做到:
public static class TcpPort{
public static final int HTTP = 80;
public static final int TELNET = 23;
public static final int SMTP = 25;
public static final int SSH = 22;
public static final int GOPHER = 70;
}
但我的感觉是enum
还是比较好。我的 enum
方法是否可行?或者有其他方法吗?
我的感觉是,in purposes only for switch
statement enum
在你的情况下是多余的,最好只使用 final static int
常量。例如内存经济。
此外,Joshua Bloch 在他的 Effective Java
中建议在他的 Item 30: Use enums instead of int constants
中使用 enum
s 而不是 int
常量。但恕我直言,这是 enum
用于更复杂情况的正确方法,然后只需替换 c
#define
构造。
UPDATE:正如作者在他对我的回答的评论中提到的,他想知道是否使用 enum
通常比 int
常量更好.在这种情况下,这样的问题就变得重复了(见 Java: Enum vs. Int),我的回答是: 一般来说 enum
更好,为什么 - 看看 Joshua Bloch 的 Item 30
,正如我之前提到的。
您在这里混淆了两个概念。 #define 允许你使用 preprocessor。编译器只会知道您定义的值。
在 Java 中,仅对端口号使用枚举似乎不合理,因为我认为它们应该是可配置的。
我建议使用工厂接口(由默认类型的枚举包围,允许第 3 方添加新接口 [OOP]。
一般来说,我不会将枚举用于常量,只是因为它们应该在适当的 class 范围内。
如果您想提高可读性,可以使用 static import 导入常量。*
*我认为静态导入是不好的做法。
您可以像这样创建几个 类:
package com.ggl.testing;
import java.util.ArrayList;
import java.util.List;
public class TCPPort {
private List<Port> ports;
public TCPPort() {
this.ports = new ArrayList<Port>();
this.ports.add(new Port("HTTP", 80));
this.ports.add(new Port("TELNET", 23));
this.ports.add(new Port("SMTP", 25));
this.ports.add(new Port("SSH", 22));
this.ports.add(new Port("GOPHER", 70));
}
public Port getPortByName(String portName) {
for (Port p : ports) {
if (portName.equals(p.getPortName())) {
return p;
}
}
return null;
}
public Port getPortByNumber(int portNumber) {
for (Port p : ports) {
if (portNumber == p.getPortNumber()) {
return p;
}
}
return null;
}
public class Port {
private final int portNumber;
private final String portName;
public Port(String portName, int portNumber) {
this.portName = portName;
this.portNumber = portNumber;
}
public int getPortNumber() {
return portNumber;
}
public String getPortName() {
return portName;
}
}
}
我正在尝试做一些在 C:
中通常看起来像这样的事情typedef enum {
HTTP =80,
TELNET=23,
SMTP =25,
SSH =22,
GOPHER=70} TcpPort;
方法一
这是我在 Java 中的内容,使用 enum
:
public static enum TcpPort{
HTTP(80),
TELNET(23),
SMTP(25),
SSH(22),
GOPHER(70);
private static final HashMap<Integer,TcpPort> portsByNumber;
static{
portsByNumber = new HashMap<Integer,TcpPort>();
for(TcpPort port : TcpPort.values()){
portsByNumber.put(port.getValue(),port);
}
}
private final int value;
TcpPort(int value){
this.value = value;
}
public int getValue(){
return value;
}
public static TcpPort getForValue(int value){
return portsByNumber.get(value);
}
}
方法 1 - 问题
我发现我不得不在不同的地方重复这个模式,但我想知道:有没有更好的方法?特别是因为:
- 这看起来很复杂而且不够优雅,
- 它还将编译时间转移到 运行 时间。
我使用此映射的原因之一是因为它在 switch 语句中看起来更好,例如:
switch(tcpPort){
case HTTP:
doHttpStuff();
break;
case TELNET:
doTelnetStuff();
break;
....
}
我想枚举也有更强的类型安全性的好处。
方法二 我知道我可以做到:
public static class TcpPort{
public static final int HTTP = 80;
public static final int TELNET = 23;
public static final int SMTP = 25;
public static final int SSH = 22;
public static final int GOPHER = 70;
}
但我的感觉是enum
还是比较好。我的 enum
方法是否可行?或者有其他方法吗?
我的感觉是,in purposes only for switch
statement enum
在你的情况下是多余的,最好只使用 final static int
常量。例如内存经济。
此外,Joshua Bloch 在他的 Effective Java
中建议在他的 Item 30: Use enums instead of int constants
中使用 enum
s 而不是 int
常量。但恕我直言,这是 enum
用于更复杂情况的正确方法,然后只需替换 c
#define
构造。
UPDATE:正如作者在他对我的回答的评论中提到的,他想知道是否使用 enum
通常比 int
常量更好.在这种情况下,这样的问题就变得重复了(见 Java: Enum vs. Int),我的回答是: 一般来说 enum
更好,为什么 - 看看 Joshua Bloch 的 Item 30
,正如我之前提到的。
您在这里混淆了两个概念。 #define 允许你使用 preprocessor。编译器只会知道您定义的值。
在 Java 中,仅对端口号使用枚举似乎不合理,因为我认为它们应该是可配置的。
我建议使用工厂接口(由默认类型的枚举包围,允许第 3 方添加新接口 [OOP]。
一般来说,我不会将枚举用于常量,只是因为它们应该在适当的 class 范围内。
如果您想提高可读性,可以使用 static import 导入常量。*
*我认为静态导入是不好的做法。
您可以像这样创建几个 类:
package com.ggl.testing;
import java.util.ArrayList;
import java.util.List;
public class TCPPort {
private List<Port> ports;
public TCPPort() {
this.ports = new ArrayList<Port>();
this.ports.add(new Port("HTTP", 80));
this.ports.add(new Port("TELNET", 23));
this.ports.add(new Port("SMTP", 25));
this.ports.add(new Port("SSH", 22));
this.ports.add(new Port("GOPHER", 70));
}
public Port getPortByName(String portName) {
for (Port p : ports) {
if (portName.equals(p.getPortName())) {
return p;
}
}
return null;
}
public Port getPortByNumber(int portNumber) {
for (Port p : ports) {
if (portNumber == p.getPortNumber()) {
return p;
}
}
return null;
}
public class Port {
private final int portNumber;
private final String portName;
public Port(String portName, int portNumber) {
this.portName = portName;
this.portNumber = portNumber;
}
public int getPortNumber() {
return portNumber;
}
public String getPortName() {
return portName;
}
}
}