Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java8中重写枚举中的方法有什么原因吗_Java_Enums_Java 8 - Fatal编程技术网

在Java8中重写枚举中的方法有什么原因吗

在Java8中重写枚举中的方法有什么原因吗,java,enums,java-8,Java,Enums,Java 8,正如所指出的,lambda提供了一种非常优雅的方式来指定单个枚举值的行为 在Java 8之前,我通常会将其实现为: enum Operator { TIMES { public int operate(int n1, int n2) { return n1 * n2; } }, PLUS { public int operate(int n1, int n2) { return

正如所指出的,lambda提供了一种非常优雅的方式来指定单个枚举值的行为

在Java 8之前,我通常会将其实现为:

enum Operator {
    TIMES {
        public int operate(int n1, int n2) {
            return n1 * n2;
        }
    },
    PLUS {
        public int operate(int n1, int n2) {
            return n1 + n2;
        }
    };

    public int operate(int n1, int n2) {
        throw new AssertionError();
    }            
}
现在我倾向于使用:

enum Operator {
    TIMES((n1, n2) -> n1 * n2),
    PLUS((n1, n2) -> n1 + n2);

    private final BinaryOperator<Integer> operation;

    private Operator(BinaryOperator<Integer> operation) {
        this.operation = operation;
    }

    public int operate(int n1, int n2) {
        return operation.apply(n1, n2);
    }
}
enum运算符{
次数((n1,n2)->n1*n2),
加上((n1,n2)->n1+n2);
私有最终二进制运算符操作;
专用运算符(二进制运算符操作){
这个操作=操作;
}
公共int操作(int n1、int n2){
返回操作。应用(n1,n2);
}
}
这似乎要优雅得多

我现在想不出重写特定枚举值的方法的理由。所以我的问题是,现在是否有充分的理由在
enum
中使用方法重写,还是应该始终首选函数接口

如果您查看在这个
enum
场景中使用lambda表达式的优势,您可能会注意到这些优势在Java 8之前的变体中都消失了。它既不比旧的专用
enum
变体更具可读性,也不能提高性能。此外,
接口BinaryOperator
在Java8之前是不存在的,因此您需要将它添加到代码库中以遵循此方法

在Java8之前的代码中使用这种委托方法的主要原因是,如果您计划很快切换到Java8,那么可以简化迁移


更新您的更新问题:

如果您主要关注Java 8用例,我建议在所有
enum
用例都有不同的行为时始终使用委派方法,这些行为仍然遵循类似的模式,这可以从使用lambda表达式中获益,就像在您的示例中实现操作符时一样

一个反例是
enum
,其中大多数都有一个共同的行为,仅在一种或几种情况下会被覆盖。例如:

enum Tokens {
    FOO, BAR, BAZ, AND, A, LOT, MORE // etc …

    /** Special Token End-Of-File */
    EOF {
        @Override
        public boolean matches(String input, int pos) {
            return input.length()==pos;
        }
    };

    // all ordinary tokens have the same behavior
    public boolean matches(String input, int pos) {
        return input.length()-pos >= name().length()
          && input.regionMatches(pos, name(), 0, name().length());
    }
}

我认为在第一个代码中应该是
public int operate
。在一个枚举中,可以有许多方法相互调用。它们的签名可能与任何标准功能接口都不匹配。顺便说一句,在您的第一个代码片段中,您的operate()方法应该声明为抽象的,而不是提供实现。另一种方法(在您的特定示例中)是
enum Operator implements BinaryOperator
,然后直接实现
apply
。我喜欢使用lambdas的解决方案,它看起来比方法重写干净得多。顺便说一句,您可以使用接口实现此逻辑。谢谢。在发布这篇文章之前,我还没有找到答案——我真的无法在这么短的时间内找到搜索的工作!话虽如此,我不确定你是否真的回答了我的问题。我不是问新方法是否更好(我相信是的)但是否有任何理由重写枚举中的方法?我已经编辑了这个问题,以便更清楚地说明我的问题。这是一个合理的答案,但默认行为可以通过为字段指定默认lambda的空构造函数轻松实现。@sprint:当然,您可以用两种方式实现这两个示例。这不会错的。只是在一种情况下,委托样式在可读性和启动时间方面具有优势,而在另一种情况下,重写样式则领先一小步。我们不是在谈论基本规则。“我会一直用同样的方法”也是一个合理的原则。(尽管我更喜欢的原则是“我迟早会质疑它,即使它是我自己的代码”)我喜欢你的最后一条原则!