136

I have a class full of utility functions. Instantiating an instance of it makes no semantic sense, but I still want to call its methods. What is the best way to deal with this? Static class? Abstract?

Nick Heiner
  • 119,074
  • 188
  • 476
  • 699

8 Answers8

169

Private constructor and static methods on a class marked as final.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
David Robles
  • 9,477
  • 8
  • 37
  • 47
  • 21
    @matt b: As David Robles points out in his answer, you do not need to make the class final... it cannot be subclassed because a subclass will be unable to invoke a super class constructor because it is private. However... no harm in being explicit. But jfyi :-). – Tom Dec 04 '09 at 07:07
95

According to the great book "Effective Java":

Item 4: Enforce noninstantiability with a private constructor

- Attempting to enforce noninstantiability by making a class abstract does not work.

- A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor:

// Noninstantiable utility class
public class UtilityClass
{
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
}

Because the explicit constructor is private, it is inaccessible outside of the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees that the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive, as the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown above.

As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

David Robles
  • 9,477
  • 8
  • 37
  • 47
  • 1
    Why did you choose `AssertionError` over other alternatives like `IllegalStateException`, `UnsupportedOperationException`, etc? – Pacerier Jun 25 '14 at 00:36
  • @Pacerier See [this](http://stackoverflow.com/questions/398953/what-is-the-preferred-throwable-to-use-in-a-private-utility-class-constructor). – bcsb1001 Oct 31 '14 at 14:11
  • @bcsb1001, That brings us to [this](http://stackoverflow.com/questions/398953/what-is-the-preferred-throwable-to-use-in-a-private-utility-class-constructor/399074#comment41967347_399074). – Pacerier Oct 31 '14 at 23:00
21

Sounds like you have a utility class similar to java.lang.Math.
The approach there is final class with private constructor and static methods.

But beware of what this does for testability, I recommend reading this article
Static Methods are Death to Testability

crowne
  • 8,456
  • 3
  • 35
  • 50
6

Just to swim upstream, static members and classes do not participate in OO and are therefore evil. No, not evil, but seriously, I would recommend a regular class with a singleton pattern for access. This way if you need to override behavior in any cases down the road, it isn't a major retooling. OO is your friend :-)

My $.02

Bennett Dill
  • 2,875
  • 4
  • 41
  • 39
  • 19
    Singletons are considered evil too. – Dan Dyer Dec 04 '09 at 02:08
  • You are correct, I wonder which is considered worse. Ultimately I like to practice the solution that makes the most sense, it's entirely possible a static class is the way to go. The thing is if all methods are static, why have a private ctor? To me the private ctor is used with singleton patterns. If 'they' want an instance of a class with no members, let them have it ;-) – Bennett Dill Dec 04 '09 at 02:11
  • 3
    You use the private constructor to prevent anyone from instantiating or subclassing the class. See David Robles' answer: http://stackoverflow.com/questions/1844355/java-static-class/1844388#1844388 – rob Dec 04 '09 at 02:30
  • 5
    singleton is not more evil than dependency injection:) – irreputable Dec 04 '09 at 02:43
  • 13
    OO has its place, but there are times when it just isn't practical, or it would be a waste of resources--for instance, something as simple as Math.abs(). There's no reason to instantiate an object just for the sake of instantiating an object, when a static method call would have served you just as well without any of the O-O-overhead. ;) – rob Dec 04 '09 at 02:43
  • @rob re private constructor. Just to make sure methodologies aren't blending, if the class at hand is comprised of static members, it has no members participating in OO and subclassing it get's you nothing. So why have a private ctor on a class with static methods. To me if you want to prevent subclassing, final is the way to go. Now, if you're creating a class that you want to use in a singleton pattern, then a private ctor makes sense. Because you can place the static instance on the class and it can be responsible for the single instance. – Bennett Dill Dec 04 '09 at 02:49
  • 2
    @rob re OO, I agree, Math.Abs probably never needs an instance. When I hear "i have a utility class", I see Math.Avg(), where you now need to add supported for a weighted average. I see a Url generator, param in, url out that needs to be refactored to support href, or url only, etc etc. For these reasons, having the OO based utility class can pay back. Also, now I'll drop the standard OO defensive tactic, testing! /me ducks – Bennett Dill Dec 04 '09 at 02:53
  • @rob: Can't argue too much with that for pure functions. For everything else, static/singleton/global are pretty much all evil :) – kyoryu Dec 04 '09 at 03:20
  • I personally consider it as a fallacy of the Java language not to have functions living outside classes (as e.g. in C++), so imho the workaround proposed (non-instantiable class with static functions) is very valid. – Maximilian Schulz Oct 11 '18 at 09:27
3

comment on the "private constructor" arguments: come on, developers are not that stupid; but they ARE lazy. creating an object then call static methods? not gonna happen.

don't spend too much time to make sure your class cannot be misused. have some faith for your colleagues. and there is always a way to misuse your class no matter how you protect it. the only thing that cannot be misused is a thing that is completely useless.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • 8
    A someone who has seen (in production code, not jsut student code) object.staticMethod I think you overestimate the abilities of Joe Random Programmer! :-P – TofuBeer Dec 04 '09 at 02:49
2
  • Final class and private constructor (good but not essential)
  • Public static methods
fastcodejava
  • 39,895
  • 28
  • 133
  • 186
1

There's no point in declaring the class as static. Just declare its methods static and call them from the class name as normal, like Java's Math class.

Also, even though it isn't strictly necessary to make the constructor private, it is a good idea to do so. Marking the constructor private prevents other people from creating instances of your class, then calling static methods from those instances. (These calls work exactly the same in Java, they're just misleading and hurt the readability of your code.)

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
-1

You can use @UtilityClass annotation from lombok https://projectlombok.org/features/experimental/UtilityClass

user811602
  • 1,314
  • 2
  • 17
  • 47
  • Following the link, it's experimental and use is not encouraged ('due to fundamental issues with non-star static imports') – jedwidz Aug 04 '22 at 09:32