Are interfaces a valid substitute for utility classes in Java 8?

Robby Cornelissen picture Robby Cornelissen · Jun 18, 2015 · Viewed 9.3k times · Source

For the past decade or so, I've been using the pattern below for my Java utility classes. The class contains only static methods and fields, is declared final so it can't be extended, and has a private constructor so it can't be instantiated.

public final class SomeUtilityClass {
    public static final String SOME_CONSTANT = "Some constant";

    private SomeUtilityClass() {}

    public static Object someUtilityMethod(Object someParameter) {
        /* ... */

        return null;
    }
}

Now, with the introduction of static methods in interfaces in Java 8, I lately find myself using a utility interface pattern:

public interface SomeUtilityInterface {
    String SOME_CONSTANT = "Some constant";

    static Object someUtilityMethod(Object someParameter) {
        /* ... */

        return null;
    }
}

This allows me to get rid of the constructor, and a lot of keywords (public, static, final) that are implicit in interfaces.

Are there any downsides to this approach? Are there any benefits to using a utility class over a utility interface?

Answer

Tagir Valeev picture Tagir Valeev · Jun 18, 2015

You should use interface only if you expect that somebody would implement it. For example, java.util.stream.Stream interface has a bunch of static methods which could be located in some Streams or StreamUtils class prior to Java 8. However it's a valid interface which has non-static methods as well and can be implemented. The java.util.Comparable is another example: all static methods there just support the interface. You cannot forbid users from implementing your public interface, but for utility class you can forbid them to instantiate it. Thus for the code clarity I suggest not to use interfaces unless they are intended to be implemented.

A note regarding @saka1029 answer. While it's true that you cannot define helper private methods and constants in the same interface, it's not a problem to create a package-private class in the same package like MyInterfaceHelper which will have all the necessary implementation-related stuff. In general package-private classes are good to hide your implementation details from the outer world.