What is best practice in Java 8 when I need a bunch of stateless utility methods. Is it right to have an interface that will not be implemented by anyone i.e. public interface Signatures
and public interface Environments
, or is it better to do it the old way - have public final class Signatures
and public final class Environments
with private constructors || enums?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
The main purpose of interfaces is to provide a type and a vocabulary of operations (methods) on that type. They're useful and flexible because they allow multiple implementations, and indeed they are designed to allow implementations that are otherwise unrelated in the class hierarchy.
The question asks,
This seems to me to cut against the grain of interfaces. One would have to look around the API to determine that there are no classes that implement this interface, and that there are no producers or consumers of this interface. Somebody might be confused and try to create an implementation of the interface, but of course they wouldn't get very far. While it's possible to have a "utility interface" with all static methods, this isn't as clear as the old unconstructible final class idiom. The advantage of the latter is that the class can enforce that no instances can ever be created.
If you look at the new Java 8 APIs, you'll see that the final class idiom is still used despite the ability to add static methods on interfaces.
Static methods on interfaces have been used for things like factory methods to create instances of those interfaces, or for utility methods that have general applicability across all instances of those interfaces. For example, see the
Stream
andCollector
interfaces injava.util.stream
. Each has static factories:Stream.of()
,Stream.empty()
, andCollector.of()
.But also note that each has companion utility classes
StreamSupport
andCollectors
. These are pure utility classes, containing only static methods. Arguably they could be merged into the corresponding interfaces, but that would clutter the interfaces, and would blur the relationship of the methods contained in the classes. For example,StreamSupport
contains a family of related static methods that are all adapters betweenSpliterator
andStream
. Merging these intoStream
would probably make things confusing.In a good object oriented design, there are not many (if any) stateless utility methods.
The best technique I've come to deal with is to use state (Objects) to deal with the function.
So instead of doing
I do
This has a few advantages. One being that it can be unloaded from memory much more easily. Another being that you can save on the number of type identifying interfaces, you can pass utility methods between methods, and a final being that you can leverage the Java type hierarchy.
The costs are minimal. Basically you have to alter how the method is applied.
Naturally you'd never write a full method to encapsulate an object oriented function, but I had to show an example...
Static methods in interfaces were added with two primary purposes:
In case of poor implementation in subclasses static interface methods can be used to provide checks (e.g. if a value is null).
Avoid using general utility classes (like
Collections
) and calling static methods through their proper interface.So, it is a very good practice if you intend to share functionality to the corresponding classes.
update:
If you wish to build a pure collection of functions then you may want to use the abstract class with static methods and a private constructor.
I would use the final class. Communicates to me better that it is a helper class with some utility methods. An interface definition is something I would expect to be implemented and the methods to be there to assist someone implement the interface.