12

Why is it a good practice to mark a class with only private constructors as final? My guess is, it is to let other programmers know that it cannot be sub-classed.

rest_day
  • 858
  • 2
  • 13
  • 28

5 Answers5

14

It is often considered (e.g. by Josh Bloch and the designers of C#) good practice to mark everything as final unless you have an explicit reason not to. Assuming you mean class, you're correct that a class with only private constructors can't be subclassed. Thus, the final could be considered redundant, but as you say it has value for documentation. As Marc suggests, it may also aid optimization.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • “Often considered” by whom? [citation needed] – Donal Fellows Jun 02 '10 at 09:58
  • 2
    mark everything as final? I think you mean variables and parameters. But it isn't a good idea to mark all classes and methods as final. This would limit the extensibility of your application daramtically. – Hardcoded Jun 02 '10 at 09:59
  • 4
    @Hardcoded, he wrote "mark everything as final **unless you have an explicit reason not to** ". I.e. you only allow extension of classes _designed to be extensible_. – Péter Török Jun 02 '10 at 10:04
  • 1
    @Donal, Josh Bloch ("Design and document for inheritance, or else prohibit it") and the designers of C# both believe non-extensibility should be the default. See this [previous question](http://stackoverflow.com/questions/657987/open-closed-principle-and-java-final-modifier). – Matthew Flaschen Jun 02 '10 at 10:12
  • My point was that it's better to back the part of your answer that seems contentious with a reference to the authority (or SO question) that you're following. (Personally, I philosophically disagree with their point in general — I tend to go for an open world model, though with strong use of delegation – but that's not an argument I intend to have here.) – Donal Fellows Jun 02 '10 at 10:28
6

Making a class final has some (small) performance gain, because the JIT compiler can inline functionality from that class. I don't know if that qualifies as 'good practice', but I see the advantages.

Marc
  • 3,550
  • 22
  • 28
  • 2
    Doesn't the JIT compiler see anyway whether that class has any concrete subclasses loaded and whether a method is overridden? I would imagine that it can inline anyway in such case, regardless of whether or not the class/method is declared `final`. Then again, I am not a JIT expert, just curious :-) – Péter Török Jun 02 '10 at 09:50
  • 7
    HotSpot determines whether the class has a subclass loaded. It doesn't make a difference if the class is marked `final` or not. – Tom Hawtin - tackline Jun 02 '10 at 09:50
  • This has interesting implications. For example, if you dynamically load a subclass of a class that previously had no loaded subclasses, the HotSpot compiler needs to recompile the class! – Stephen C Jun 02 '10 at 10:01
  • @Stephen C: that is what I thought. Maybe this behavior has changed in later version of the JVM. – Marc Jun 02 '10 at 10:07
  • @Stephen C: It's actually the compiled calling code that needs to be backed out. – Tom Hawtin - tackline Jun 03 '10 at 00:47
  • @Tom Hawtin - ah! that makes sense! – Stephen C Jun 03 '10 at 01:01
4

You mean "a class with private constructor" do you?

A final class can't be subclassed. This may represent a design decision. Not all classes are designed to be subclassed, so if yours is not, it is best to mark it explicitly, to avoid subtle bugs later.

A class with private constructors only can't be instantiated by the outside world (neither subclassed). This may be useful for e.g. singletons, or classes where you want to control what instances of the class are created. E.g. before Java5, the typesafe enum pattern used this.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
2

We mark the class as final class by making constructor as private, to avoid sub-classing.

This is good practice, in cases where we don’t want people to override our class methods and change the functionality or add the functions to our class.

For example, classes String and Math are final classes, which we can’t extend or subclass, this is to make sure that no one will change their behavior.

sap
  • 679
  • 3
  • 8
  • 21
1

A final class with private constructor:

  • Class can not have sub-classes, we can not extent final class.
  • Class having private constructor, we can not create the object of that class.

It means other methods of the class will be static, so that class can access them.

Rolf ツ
  • 8,611
  • 6
  • 47
  • 72
AKT
  • 182
  • 1
  • 8
  • I don't think that the second point holds true. We can still create objects of a class whose constructors are all private via a static factory method. – Grant Feb 28 '20 at 13:35