44

I have a quite simple question:

I want to have a Java Class, which provides one public static method, which does something. This is just for encapsulating purposes (to have everything important within one separate class)...

This class should neither be instantiated, nor being extended. That made me write:

final abstract class MyClass {
   static void myMethod() {
      ...
   }
   ... // More private methods and fields...
}

(though I knew, it is forbidden).

I also know, that I can make this class solely final and override the standard constructor while making it private.

But this seems to me more like a "Workaround" and SHOULD more likely be done by final abstract class...

And I hate workarounds. So just for my own interest: Is there another, better way?

Sauer
  • 1,429
  • 4
  • 17
  • 32
  • 5
    Why do you want to make the class abstract? Abstract class means that there are some declared but unimplemented methods, which **extending classes** _must_ implement. – Aleks G Mar 08 '12 at 13:46
  • 7
    @Aleks G: That is not true... Abstract class means: You cannot directly instantiate it. You don't neccessarily HAVE TO define abstract methods within that class... Of course you are right. Normally you would use abstract classes like you said. But that is just a "point-of-view" thing. I always make my larger factory classes abstract without defining abstract methods. – Sauer Mar 08 '12 at 14:36
  • 1
    @AleksG you don't have do define abstract methods on an abstract class. Its an oddity... Abstract means the class cant be directly instantiated and that its child classes must implement it's abstract methods or declare them abstract too. – Felype Jun 07 '13 at 11:47
  • 2
    @Sauer I have also came to a point when I NEEDED to declare a 'namespace', a class just to contain static methods and variables accessible from any part of my code and it shouldn't be able to be instantiated nor inherited. I think there's nothing wrong on declaring a 'final abstract' class, java language definition seems to be a bit broken at that point. Perhaps they could add 'final abstract' definition and enforce all of the class' fields to be static. Well, that would surely be an agression to OOP standards XD – Felype Jun 07 '13 at 11:51
  • @Felype: Yes, very good proposal! But why not a new keyword like "class" -> "namespace"? – Sauer May 30 '16 at 10:12
  • Because Java has "hugged" and stickied to the `singleton` concept. I don't personally feel comfortable using singleton design pattern over static fields and methods (doesn't feel natural to me), blame my cpp precedence. – Felype May 30 '16 at 17:35
  • 1
    Ah and also, C# seems to have the "static class" concept, which seems to be the exact concept the OP intended to describe. – Felype May 30 '16 at 17:46

9 Answers9

58

You can't get much simpler than using an enum with no instances.

public enum MyLib {;

   public static void myHelperMethod() { }
}

This class is final, with explicitly no instances and a private constructor.

This is detected by the compiler rather than as a runtime error. (unlike throwing an exception)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 9
    it is perfect solution. I do not understand why people do not vote it. – AlexR Mar 08 '12 at 14:01
  • 3
    @AlexR I use enum for singletons as well for the same reason. You are explicitly saying how many instances there can be. `enum` can extend interfaces in the case of singletons. – Peter Lawrey Mar 08 '12 at 14:03
  • 5
    Peter Lawrey 1 - 0 Joshua Bloch ;-) (Funny that JB does not mention that when he advocates using enum so strongly for singletons) – assylias Mar 08 '12 at 14:04
  • 6
    It does mean that the type does come with some rather odd static and instance methods. – Tom Hawtin - tackline Mar 08 '12 at 14:09
  • Hmm I like that idea! But I cannot judge, how much "overhead" an enumeration means. It provides methods and stuff, which I will never use (like Tom Hawtin said). I will stick to the "workadound" with the private constructor... – Sauer Mar 08 '12 at 14:40
  • 4
    @Sauer If you don't use methods, they have no over head. It worth thinking about your overhead writing code you don't need to. – Peter Lawrey Mar 08 '12 at 14:59
  • 1
    It's funny though, because Singletons seem to be frowned upon now due to new emerging practices. The `enum` Singleton is so 2008. Today decoupling and dependency injection is the thing. Then tomorrow it will be shunned, and reactive programming will be the next craze. Coding feels prone to fashion and trends just as much as the clothing industry. – tmn Apr 30 '15 at 00:17
  • 1
    @ThomasN. What is bad about singletons is when they are used for shared state. This makes testing and MT code harder. However use singletons as stateless implementations of a strategy and they are good. – Peter Lawrey Apr 30 '15 at 07:25
  • 5
    using an enum is better than the accepted solution, as it does not leave unreachable code that cannot be covered by unit tests (unless one uses reflection) – arcuri82 Feb 05 '16 at 12:53
  • @arcuri82 That's one thing. But an "enum" in Java is usually ment to be an enumeration of different values a specific type can take. In my usage, this is not the case and might confuse other programmers who'd expect an enum to be an ... enum :-) – Sauer Aug 13 '18 at 18:10
  • 1
    @Sauer an enum with no instances does exactly that, it shows there is no instances. – Peter Lawrey Aug 13 '18 at 21:02
47

Reference: Effective Java 2nd Edition Item 4 "Enforce noninstantiability with a private constructor"

public final class MyClass { //final not required but clearly states intention
    //private default constructor ==> can't be instantiated
    //side effect: class is final because it can't be subclassed:
    //super() can't be called from subclasses
    private MyClass() {
        throw new AssertionError()
    }

    //...
    public static void doSomething() {}
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • 39
    @LuiggiMendoza this is _not_ a singleton pattern. There is no instance at all here. – M Platvoet Mar 08 '12 at 13:50
  • Yes, but Singleton Pattern could be a suited solution for this. – Luiggi Mendoza Mar 08 '12 at 13:52
  • I'd make it `final`, not that that should make any difference since JDK6/J2SE 5.0. – Tom Hawtin - tackline Mar 08 '12 at 14:08
  • 1
    @TomHawtin-tackline Edited - I agree it is better from a readability perspective even if it does not make a difference. – assylias Mar 08 '12 at 14:10
  • Well, a class can be *within* this class and use the private constructor, the `final` could make a tiny bit of difference there. That said, if somebody wants to muck about *in* your class then there is no stopping them. The assertion error can be left out, only creates unreachable code, I normally use a comment instead. – Maarten Bodewes Jul 26 '14 at 23:15
  • This solution will negatively affect code coverage reports, as that constructor is never executed – arcuri82 Feb 05 '16 at 12:50
  • @arcuri82 agreed - but is that a problem? See also: http://stackoverflow.com/q/4520216/829571 – assylias Feb 05 '16 at 12:52
  • @assylias it is a problem depending on how you use code coverage results. If you use it to point out under tested classes (which you did not write) that might need more tests, then such type of constructors just leads to a lot wasted time (especially on large systems with thousands of classes). – arcuri82 Feb 06 '16 at 10:28
8

No, what you should do is create a private empty constructor that throws an exception in it's body. Java is an Object-Oriented language and a class that is never to be instantiated is itself a work-around! :)

final class MyLib{
    private MyLib(){
        throw new IllegalStateException( "Do not instantiate this class." );
    }

    // static methods go here

}
Sled
  • 18,541
  • 27
  • 119
  • 168
  • @assylias: *"the class will be final because it can't be subclassed"*. It depends on your definition of "final". It's not as if the class was implicitly made *final* because of the private constructor (in the way, say, interface methods that aren't declared as public are implicitly public). Putting for example *public final* or simply *public* **shall** lead to two different *.class* files being generated: with *final* the *.class* has its access flags set to 0x31 (public final) while with only *public* its access flags are 0x21. You cannot extend it but it's still not *final*... – TacticalCoder Mar 08 '12 at 14:14
  • @ArtB But you would agree, that the following is also nonsens?: The alternative would be, to write an "object-class" and call the constructor once, which does all the work... There is no point in using this object any further. It has no destructor, no getter, no setter... The object is pointless in this case, because all objects will be exactly the same. This is exactly, what static methods are for. And it is good practice, to encapsulate stuff into separat classes (i.e. "files"). Of course I can stuff everything in my calling class. But that would be too much... – Sauer Mar 08 '12 at 14:30
  • @Sauer It's hard to offer an alternative without knowing specifics, but after working on becoming better with object-oriented design principles I find that very rarely are static methods needed. The only cases I can really justify are those where you are adding methods that ought to have existed in the class or are for dealing with null issues. – Sled Mar 08 '12 at 15:13
  • 1
    @ArtB Of course it is up to you, how you design your structure. But to me, static methods are a very valid part of each object oriented programm. I also write APIs at my company and I often use static methods to ENFORCE object oriented coding. Static methods are used to handle "static" and complex algorithms which are working WITH objects. That keeps the real object classes less complex and easier to understand (pojos). Sometimes there is no point in stuffing complex algorithms into object classes... – Sauer Mar 13 '12 at 14:37
  • 1
    @Sauer I would recommend you at least try stuffing those algorithims into objects as an excercise. I've found that over time I've found neat ways to include those algorithims in to objects, or that some design pattern solves this. I suggest that it maybe be correct more often than you suspect to push things into objects from static methods. YMMV – Sled Mar 13 '12 at 21:16
4

No, abstract classes are meant to be extended. Use private constructor, it is not a workaround - it is the way to do it!

scibuff
  • 13,377
  • 2
  • 27
  • 30
3

Declare the constructor of the class to be private. That ensure noninstantiability and prevents subclassing.

blalasaadri
  • 5,990
  • 5
  • 38
  • 58
1

You can't mark a class as both abstract and final. They have nearly opposite meanings. An abstract class must be subclassed, whereas a final class must not be subclassed. If you see this combination of abstract and final modifiers, used for a class or method declaration, the code will not compile.

Sachindra N. Pandey
  • 1,177
  • 17
  • 15
1

The suggestions of assylias (all Java versions) and Peter Lawrey (>= Java5) are the standard way to go in this case.

However I'd like to bring to your attention that preventing a extension of a static utility class is a very final decision that may come to haunt you later, when you find that you have related functionality in a different project and you'd in fact want to extend it.

I suggest the following:

public abstract MyClass {

    protected MyClass() {
    }

    abstract void noInstancesPlease();

    void myMethod() {
         ...
    }
    ... // More private methods and fields...

}

This goes against established practice since it allows extension of the class when needed, it still prevents accidental instantiation (you can't even create an anonymous subclass instance without getting a very clear compiler error).

It always pisses me that the JDK's utility classes (eg. java.util.Arrays) were in fact made final. If you want to have you own Arrays class with methods for lets say comparison, you can't, you have to make a separate class. This will distribute functionality that (IMO) belongs together and should be available through one class. That leaves you either with wildly distributed utility methods, or you'd have to duplicate every one of the methods to your own class.

I recommend to never make such utility classes final. The advantages do not outweight the disadvantages in my opinion.

Durandal
  • 19,919
  • 4
  • 36
  • 70
  • I got your point and it made me think about my design. But in my case, I really really don't want to let someone extend my class. That is why it is default visibility "final class MyClass" (without public). It is only valid within my package and noone should be able to use it outside that package. And noone should be able to extend it inside the package. But anyway: Nice idea with that "noInstancesPlease" abstract method... I will keep that in mind – Sauer Mar 13 '12 at 14:42
0

This is very simple explanation in plain English.An abstract class cannot be instantiated and can only be extended.A final class cannot be extended.Now if you create an abstract class as a final class, how do you think you're gonna ever use that class, and what is,in reality, the rationale to put yourself in such a trap in the first place?

Elijah Dayan
  • 442
  • 6
  • 19
  • 1
    You are right. But, as I said: I want to use this class for a Toolbox of static methods. So I neither want to instatiate, nor to extend it. – Sauer May 30 '16 at 10:04
-2

Check this Reference Site..

Not possible. An abstract class without being inherited is of no use and hence will result in compile time error.

Thanks..

Java Man
  • 1,854
  • 3
  • 21
  • 43