Java枚举(或int常量)vs c enum

时间:2015-04-29 13:24:21

标签: java enums coding-style

我正试图在C中做一些通常看起来像这样的事情:

typedef enum {
    HTTP  =80, 
    TELNET=23, 
    SMTP  =25, 
    SSH   =22, 
    GOPHER=70} TcpPort;

方法1

以下是我在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 - 问题

我发现我不得不在不同的地方重复这种模式,但是想知道:有更好的方法吗?特别是因为:

  1. 这似乎令人费解,不那么优雅,
  2. 它还会将编译时的内容转移到运行时“。
  3. 我使用此映射的原因之一是因为它在switch语句中看起来更好,例如:

    switch(tcpPort){
        case HTTP:
            doHttpStuff();
            break;
        case TELNET:
            doTelnetStuff();
            break;
        ....
    }
    

    我认为使用枚举还可以提高类型安全性。

    方法2 我知道我能做到:

    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方法是否可行?还是有另一种方式?

3 个答案:

答案 0 :(得分:1)

我的感觉是,仅用于switch语句enum的目的在您的情况下是多余的,并且最好只使用final static int常量。例如记忆经济。

此外,Joshua Bloch在他的Effective Java中建议在enum中使用int而不是Item 30: Use enums instead of int constants常量。但恕我直言,enum使用更复杂的案例,然后只是替换c #define构造,这是正确的方法。

更新:正如作者在对我的回答的评论中提到的那样,他想知道如果enumint常数更好,那就是使用。在这种情况下,这样的问题会变成重复(请参阅Java: Enum vs. Int),我的回答是:一般 enum s更好,为什么 - 看看Joshua Bloch&#39; s Item 30,正如我之前提到的那样。

答案 1 :(得分:0)

你在这里混合了两个概念。 #define允许您使用preprocessor。编译器只知道您定义的值。

在Java中使用枚举仅用于端口号似乎是不合理的,因为它们应该是可配置的。

我建议使用带工厂的接口(默认类型的枚举包围,允许第三方添加新接口[OOP]。

一般来说,我不会将Enumerations用于常量,只是因为它们应该在适当的类中作用域。

如果您想提高可读性,可以导入static import的常量。*

*我会考虑静态导入不好的做法。

答案 2 :(得分:0)

你可以创建这样的几个类:

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;
        }

    }

}