是否有任何理由在Java 8中覆盖枚举中的方法

spr*_*ter 6 java enums java-8

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

在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();
    }            
}
Run Code Online (Sandbox Code Playgroud)

现在我倾向于使用:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这看起来显得更加优雅.

我现在想不出有理由重写特定枚举值的方法.所以我的问题是,有没有什么好的理由在enum现在使用方法覆盖,或者应该首选功能界面?

Hol*_*ger 5

如果你看一下这个答案总结了在这个enum场景中使用lambda表达式的优点,你可能会注意到这些优点在Java 8之前的版本中都消失了.它既不比旧的专用enum变体更具可读性,也不会提高性能.此外,interface BinaryOperator它在Java 8之前不存在,因此它是您需要添加到代码库以遵循此方法的另一个类.

如果您计划很快切换到Java 8,在Java 8之前的代码中使用此委派方法的主要原因是为了简化迁移.


更新到您更新的问题:

如果您主要关注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());
    }
}
Run Code Online (Sandbox Code Playgroud)