views:

247

answers:

7

What do you think of the following way to simulate a static class in java? You can add non static methods but you wouldn't be able to call them.

 /**
  * Utility class: this class contains only static methods and behaves as a static class.
  */
 // ... prevent instantiation with abstract keyword
 public abstract class Utilities
    {
        // ... prevent inheritance with private constructor
        private Utilities() {}

        // ... all your static methods here
        public static Person convert(String foo) {...}
    }
+3  A: 

My FindBugs plugin suggests rather final class instead of abstract class. And I use that in my project. It seems to be a widespread idiom if it became a rule that is checked by FindBugs.

Tadeusz Kopec
+2  A: 

i would say, if you habe already a private constructor

private Utilities() {}

the abstract keyword is not neccessary. rather make it final.

the difference to your version is marginal, for any practical means.

Andreas Petersson
+8  A: 

That is the usual way. However, there is not need for the abstract keyword. Using a private constructor is sufficient because

  • it prevents the creation of objects (from outside the class)
  • it prevents inheritance

The abstract keyword suggests the user that users of the class might implemented the class what is not the case here.

dmeister
Even though inheritance is prevented, I would still include the `final` keyword.
Thorarin
+2  A: 

I prefer making such classes final, but not abstract. Though it is just a matter of personal style.

By the way, I suppose it is still possible to call its instance methods if you put some energies. E.g. one can try using objenesis to create instance of class.

Rorick
+1  A: 

My suggestion is: prevent incorrect use (i.e. instantiation) by placing javadocs

Isn't that simpler? I think your teammates are able to read ;)

Megadix
This is a standard idiom in Java. Seeing such class you even don't need to read =) You figure out that it is an utility just by the first glance.
Rorick
@Megadix: It is not that they aren't able to read Javadoc. More that they don't read Javadoc. Just like many people who post Java questions to SO!
Stephen C
enforcing a non-instantiability constraint at compile-time has a great value, you should as many times as possible
dfa
+2  A: 

I'll have to agree with those above. Use "final" instead of "abstract". Remember, words like "final" and "abstract" are as much a means of communicating with your fellow programmers as they are instructions to the machine. Abstract implies that there will be descendant classes later, whereas final decidedly means that you will not, save through refactoring, see anything descended of this class (which is your intended meaning).

Further, in most standards I've seen, and consistently in my company, it is considered best practice to make the abstract class something which is specifically left unused, save as a parent of other classes. "Abstract" is treated as "blueprint" or "general structure", you would never drive an "abstract" car. On the other hand, final classes are instantiated perpetually, especially with Factory patterns.

Christopher W. Allen-Poole
+4  A: 

Item 4 in Effective Java (a very... effective book) says:

// Noninstantiable utility class
public final class Utility {

    private Utility() {
        throw new AssertionError();
    }
}

because the explicit costructor is private:

  • you cannot instantiate it
  • you cannot extend it (as if it was declared as final)

The AssertionError isn't required but it provides another small benefit: it prevents that the costructior is accidentally invoked from within the class.

You can also create a specific annotation, like @BagOfFunction, and annotate your class:

@BagOfFunctions
public final class Utility {

    private Utility() {
        throw new AssertionError();
    }
}

basically you trade a comment for a self-documenting annotation.

dfa
You should probably add the word final to your first code sample
mR_fr0g
I like this answer. Especially because the exception even prevents the creation of the object using reflection.
dmeister
Can you explain the use of the @BagOfFunctions annotation?
pjp
since javadoc shows annotations (like @GwtCompatible in this API http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html) you annotate your class to document that it is really a bag of functions
dfa