default
methods are overridable methods, but your scenario describes a utility method that is intended to be neither, part of the API nor overridable. Note that since default
methods can work on the instance only in terms of the public
methods defined in the interface, i.e. can not access any internals, there is no difference between:
interface MyInterface {
default ReturnType method(Parameter parameter) {
}
}
and
interface MyInterface {
static ReturnType method(MyInterface instance, Parameter parameter) {
}
}
regarding what the method can do. It’s only that within the default
method, you may omit the qualifying this.
when invoking other interface method, whereas in the static
method, using instance.
is mandatory. But in either case, you may invoke all public
methods of the MyInterface
instance but nothing else.
But the static
method is not overridable and you may move it to any other class to avoid it becoming part of MyInterface
’s API. But note that there is little reason to worry about the accessibility of the utility method. Since it can’t access any internals of the implementation classes, it can’t offer anything that the callers couldn’t do otherwise. It only makes it more comfortable than re‑implementing the functionality at the caller’s site. So moving the method into another class primarily documents the intention of not being part of the MyInterface
’s API. It’s no harm, if the method is public
there (to support implementations in arbitrary packages).
See for example the methods in the class StreamSupport
. They are there to aid implementing Stream
s, needed by different packages, but not part of the Stream
interface API itself. The fact that the methods there are public
does not create any harm, they don’t offer anything you couldn’t do yourself using the other available public
APIs. But it’s convenient for implementors not needing to do it themselves.