Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

enums

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?

like image 597
sprinter Avatar asked Feb 02 '15 12:02

sprinter


People also ask

Can you override an enum Java?

Enums are exactly final inner classes that extends java. lang. Enum<E> . You cannot extend, override or inherit an enum .

Should enums have methods?

The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.

Can enums be subclassed?

We've learned that we can't create a subclass of an existing enum. However, an interface is extensible. Therefore, we can emulate extensible enums by implementing an interface.

Are enums bad Java?

Many people consider Enums as a code smell and an anti-pattern in OOPs. Certain books have also cited enums as a code smell, such as the following. In most cases, enums smell because it's frequently abused, but that doesn't mean that you have to avoid them. Enums can be a powerful tool in your arsenal if used properly.


1 Answers

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. E.g.:

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());
    }
}
like image 124
Holger Avatar answered Dec 09 '22 18:12

Holger