【问题标题】:Java enum instatiate using constructor parameterJava枚举使用构造函数参数实例化
【发布时间】:2014-08-14 13:32:27
【问题描述】:

我有这个枚举:

    public enum Operation {
        ADD {
            public double apply(double a, double b) {
                return a + b;
            }
        },
        SUBTRACT {
            public double apply(double a, double b) {
                return a - b;
            }
        }
        } ;

        public abstract double apply(double a, double b);
`}`

我想像这样实例化它:

Operation op=new Operation("+");
op.aply(2,3);//now use ADD

是否可以编写一个带有字符串参数的构造函数,告诉枚举要应用哪个操作?

【问题讨论】:

  • 您错误地尝试将枚举元素视为普通的旧对象。枚举构造函数是隐式私有的(您不能将它们重新定义为其他任何东西)。你真正需要做的是Operation.ADD.apply(2, 3);
  • @JonK 添加查找是明智的,例如,如果您想从解析器调用它

标签: java enums instance


【解决方案1】:

你可以定义一个公共的静态方法来基于一个字符串得到正确的操作:

public static Operation get(String input) {
    if(input.equals("+")) {
        return ADD;
    }
    if(input.equals("-")) {
        return SUBTRACT;
    }
    throw new IllegalArgumentException();
}

那么你可以这样称呼它:

Operation op = Operation.get("+");
op.apply(2, 3);

【讨论】:

  • 你也可以在枚举里面放一个查找方法,根据输入返回正确的元素,这样设计会更好
【解决方案2】:

很遗憾,没有。您可以创建一个带有String 参数的方法,该方法返回特定的Operation,具体取决于参数是什么。示例:

public enum Operation {
    ADD("+") {
        public double apply(double a, double b) {
            return a + b;
        }
    },
    SUBTRACT("-") {
        public double apply(double a, double b) {
            return a - b;
        }
    };

    private String operationChar;

    private Operation(String s) {
        this.operationChar = s;
    }

    public static Operation getOperation(String s) {
    for (Operation o : Operation.values()) {
            if (o.operationChar.equals(s))
                return o;
        }
        return null;
    }

    public abstract double apply(double a, double b);
}

你可以这样获取实例:

Operation op = Operation.getOperation("+");
op.apply(2,3); // ADD will be used here

(您可以使用 char 而不是 String,因为大多数操作只有一个字符 (1+1, 1-1 , 1*1, 1/1))

【讨论】:

  • 我仍然会选择字符串而不是字符(例如,如果我想用 mod 而不是 % 来表示模数怎么办)
  • 是的,在这种情况下使用字符串会更好,我只是认为使用只有一个字符的字符串有点奇怪。
【解决方案3】:

您可以尝试以下示例。

它有点过度设计(您可以放弃整个“+”或“-”并按名称调用元素)但它有效。

public enum Operation {
    ADD("+") {
        public double apply(double a, double b) {
            return a + b;
        }
    },
    SUBTRACT("-") {
        public double apply(double a, double b) {
            return a - b;
        }
    };
    public abstract double apply(double a, double b);
    String type;
    Operation(String type) {
        this.type = type;
    }
    public String getType() {
        return type;
    }
    static Operation get(String type) {
        for (Operation o: Operation.values()) {
            if (o.getType().equals(type)) {
                return o;
            }
        }
        throw new NoSuchElementException();
    }
    public static void main(String[] args) throws Exception {
        System.out.println(Operation.get("+").apply(1, 2));
    }
}

输出

3.0

【讨论】:

    【解决方案4】:

    您可以在枚举中定义构造函数,但不能在枚举定义之外使用它。可用的枚举值在编译时是固定的,您不能在运行时使用new 创建更多值。如果要按符号查找枚举,则需要在代码中定义查找。

    例如通过打开符号:

    public enum Operation {
    
        ADD {/*...*/};
    
        // ...
    
        public static Operation forSymbol(String symbol) {
            switch(symbol) {
            case "+":
                return ADD;
            //...
            default:
                throw new IllegalArgumentException("Unsupported symbol: " + symbol);
            }
        }
    }
    

    或者通过与枚举一起定义符号,并在查找中使用它:

    public enum Operation {
    
        ADD("+") {/*...*/};
    
        private final String symbol;
    
        private Operation(String symbol) {
            this.symbol = symbol;
        }
    
        // ...
    
        public static Operation forSymbol(String symbol) {
            for (Operation operation : Operation.values()) {
                if (operation.symbol.equals(symbol)) return operation
            }
            throw new IllegalArgumentException("Unsupported symbol: " + symbol);
        }
    }
    

    【讨论】:

    • @JonK 哎呀,这就是在没有 IDE(或编译)的情况下键入示例所得到的。会更新。而且我还使用了== 而不是equals...我将其归咎于过多的 C# 使用
    • == 适用于枚举,因为它们保证是单例,因此如果您查看相同的元素,它们将在引用上相等。
    • @JonK 除了我在字符串上做== (symbol)...正如我所说:我责怪 C#
    • 啊!老实说,我也没注意到
    【解决方案5】:

    这是不可能的,因为枚举不能有公共构造函数(this 问题中的更多信息)。要使用Operation,您必须手动告诉编译器使用哪个Operation。这可以通过以下方式完成:

    Operation op = ADD;
    double x = op.apply(2,3);
    

    它使用 ADD 作为Operation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-30
      • 1970-01-01
      • 2011-08-20
      • 2021-08-03
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多