简体   繁体   中英

Is there any reason to override methods in enums in Java 8

As pointed out here lambdas provide a quite elegant way of specifying behaviour for individual enum values.

Before Java 8 I would normally have implemented this as:

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

Now I tend to use:

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

This seems significantly more elegant.

I cannot think of a reason to override methods for a specific enum value now. So my question is, are there any good reasons to use method overrides in an enum now or should a functional interface always be preferred?

If you look at this answer which summarizes the advantages of using lambda expression in this enum scenario you might notice that these advantages all disappear in the pre-Java 8 variant. It's neither more readable than the old specialized enum variant nor does it improve the performance. Further, the interface BinaryOperator doesn't exist before Java 8 so it's another class you would need to add to your codebase to follow this approach.

The main reason to use this delegation approach in pre-Java 8 code would be to ease the migration if you plan to switch to Java 8 soon.


Update to your updated question:

If you mainly focus on the Java 8 use case, I would recommend to always use the delegation approach when all enum cases have a different behavior which still follows a similar pattern which can benefit from using lambda expressions, as it's the case when implementing operators like in your example.

A counter-example would be an enum where most of them share a common behavior that will be overridden for one or a few cases only. Eg:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM