Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to define Predicates and Functions

When defining Predicate's or Function's, I used to create them as static final

private static final Predicate<SomeDto> SOME_PREDICATE =
                new Predicate<SomeDto>() {
                    @Override
                    public boolean apply(SomeDto input) {
                        return input.isValid();
                    }
                }

However I have noticed that there is a lot of use also with enum version, for example

private enum SomePredicate implements Predicate<SomeDto> {
        INSTANCE;

        @Override
        public boolean apply(SomeDto input) {
            return input.isValid();
        }
    }

I am aware about the enum vs static final topics, but is there any real advantage of using enum's over static final with predicates or functions?

like image 917
vtor Avatar asked Mar 20 '15 18:03

vtor


1 Answers

The main advantage of the enum singleton approach in this case is that the Predicate/Function is automatically Serializable.

Guava itself uses enums for some of its Predicate and Function implementations for this reason, among others. Josh Bloch recommends the use of enums when you want a singleton in Effective Java 2nd Ed., Item 3. To quote:

This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.

Guava exposes those singletons through static methods in its API though, avoiding the ugliness of SomePredicate.INSTANCE in user code.

like image 177
ColinD Avatar answered Sep 30 '22 12:09

ColinD