Sauer
Sauer

Reputation: 1469

Java final abstract class

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?

Upvotes: 45

Views: 45549

Answers (9)

Elijah Dayan
Elijah Dayan

Reputation: 450

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?

Upvotes: -1

Peter Lawrey
Peter Lawrey

Reputation: 533472

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)

Upvotes: 61

Sachindra N. Pandey
Sachindra N. Pandey

Reputation: 1252

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.

Upvotes: 1

Gianmarco Biscini
Gianmarco Biscini

Reputation: 435

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

Upvotes: 3

Java Man
Java Man

Reputation: 1860

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..

Upvotes: -3

Sled
Sled

Reputation: 18939

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

}

Upvotes: 8

Durandal
Durandal

Reputation: 20059

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.

Upvotes: 1

assylias
assylias

Reputation: 328568

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() {}
}

Upvotes: 47

scibuff
scibuff

Reputation: 13755

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

Upvotes: 4

Related Questions