10

I have a class that offers a collection of static utility-type methods.

On the one hand, I don't want the class to be able to be instantiated. On the other hand, I don't want to send the signal that the class should be inherited from (not that I think that it's likely).

Should this class be abstract or not?

oadams
  • 3,019
  • 6
  • 30
  • 53

8 Answers8

13

make the class final and make the default constructor private and do not provide any public constructors. that way no one can subclass it or create an instance of it.

mre
  • 43,520
  • 33
  • 120
  • 170
  • 10
    And to prevent instantiate it with reflection throw RuntimeException inside constructor :D – Pshemo Feb 15 '13 at 00:38
  • 1
    Of course, if someone on the project is trying to instantiate such a class, then the project is probably screwed anyway, so really it's a waste of time to even worry about this stuff. – rees Feb 15 '13 at 01:48
  • 1
    @mre My comment was slightly tongue-in-cheek, but not particularly cryptic. Obviously, your world is completely black and white. – rees Feb 15 '13 at 04:28
8

Don't declare it abstract; declare a private constructor, so no one, not even a subclass, can instantiate an instance of your utility class.

You can declare your class final, although if all constructors are private, then no one will be able to subclass it anyway.

To borrow the idea from Pshemo's comment in another answer, throw a RuntimeException in the constructor to prevent reflection's setAccessible method in AccessibleObject from allowing instantiation:

public class MyUtility
{
   private MyUtility()
   {
      throw new RuntimeException("Instantiation of MyUtility is not allowed!");
   }

   public static void utilityMethod()
   {
      // Your utility method here.
   }
}
rgettman
  • 176,041
  • 30
  • 275
  • 357
3

Although a top-level class can't be declared static, you can make the class non-instantiable (and practically 'static') to other classes by declaring the default constructor private, which forbids instantiation because no constructor is visible.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
2

Another version of @mre's answer

enum MyClass{
    ;//this semicolon indicates that this enum will have no instances

    //now you can put your methods
    public static void myMethod(){
        //...
    }
}

Enum by default is final and its constructor is private. Also you cant create its instance with reflection because it checks in Constructor#newInstance if you are trying to instantiate Enum object.

Community
  • 1
  • 1
Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • +1, out-of-the-box. But it does suffer from using the enum type in an unintended way that belies the meaning of "enum". – rees Feb 15 '13 at 04:52
1

What is contained in a class has no bearing on whether it should be abstract. The key take away: an abstract class must have another class extending it (a 'concrete' class); only that concrete class can be instantiated.

To prevent it from being extended, use final.

To prevent it from being instantiated, make the constructor private.

Observe that in Java these are discrete concepts.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
1

No, it is a utility class.
It should be final with a private default constuctor, to avoid instantiation. If you have checkstyle enabled you would get a warning if you dont do it.

AlexWien
  • 28,470
  • 6
  • 53
  • 83
1

In addition to all the other calls to give the class a private constructor, you should also make it final so that it is clear nothing can subclass it.

public final class Utils
{
    // prevent accidental construction.
    private Utils() 
    {  
    } 

    public static void foo()
    { 
        //util code here
    }
}
TofuBeer
  • 60,850
  • 18
  • 118
  • 163
1

Seriously, you don't have to do anything. Nothing bad will happen, nobody is going to instantiate/subclass your class.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • +1 Agreed. This is an accident that never happens. It's like putting up guardrails on a road in the desert that no one ever drives along anyway. – rees Feb 15 '13 at 04:54
  • ... in a totally flat desert, where nothing bad would happen if the car left the road. At worst, needlessly creating an instance will cause a (in the vast majority of cases, totally negligible) reduction in performance. Surely we have more important things to care about? – meriton Feb 15 '13 at 20:59