2

When we want to close a class to inheritance we are declaring class with final,

final class Myclass {}

but when we declare the constructor private it will be the same effect,

class Myclass {
     private Myclass() {}
}

But is it really the same? Is there any difference for optimization of code or readability of code? And which classes has to close to inheritance,

  1. immutable class maybe
  2. every method and member variable declared static of class

But for second option java.util.Arrays hasn't been declared with final even if all methods of Arrays are declared static.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
User8500049
  • 410
  • 3
  • 12
  • Did you see this answer: https://stackoverflow.com/questions/3952815/extends-of-the-class-with-private-constructor – 0xh3xa Mar 22 '20 at 21:10
  • Does this answer your question? [extends of the class with private constructor](https://stackoverflow.com/questions/3952815/extends-of-the-class-with-private-constructor) – Arvind Kumar Avinash Mar 22 '20 at 21:21
  • In bytecode you can subclass a class with no accessible constructors, but you can't create an instance of it **unless** the base class is `Serializable` – Tom Hawtin - tackline Mar 23 '20 at 01:16

3 Answers3

3

but when we declare ctor private it will be the same effect

Not necessarily, consider this example using static classes:

public class SOExample {
    private static class ClassWithPrivateConstructor {
        private ClassWithPrivateConstructor() {
            System.out.println("I have a private constructor");
        }
    }

    private static class ClassThatExtendsClassWithPrivateConstructor extends ClassWithPrivateConstructor {
    }

    public static void main(String[] args) {
        new ClassThatExtendsClassWithPrivateConstructor();
    }
}

This will print "I have a private constructor".

but is it really same? is there any difference for optimization of code or readablity of code. and which classes has to close to inheritance,

When a developer sees that a class is final, they understand that the intention of the author was that it should not be extended.

When a developer sees that a class has a private constructor, they understand that the class can't be instantiated. This is generally because it is either a static utility class or a singleton.

But for second option java.util.Arrays hasn't declared with final even if all methods of Arrays declared static

This is a good observation. My guess is that it probably should have been but can't be changed now for backward compatibility.

Robert Bain
  • 9,113
  • 8
  • 44
  • 63
  • 2
    Good Answer. Another reason for using a private constructor is that static factory methods provide for instantiation, such as the `of` methods on the *java.time* classes. Example: `LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;` – Basil Bourque Mar 22 '20 at 21:45
  • `final` classes have been there since 1.00 - it's really important for `String`. – Tom Hawtin - tackline Mar 23 '20 at 01:10
1

What I usually do is I make the class final and the constructor private:

  1. it removes the ambiguity about the class use (emphasising it's a utility class)
  2. it keeps the user away from what they aren't supposed to do (to initiate, to extend).

.

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class HttpTool {}

That said, there is nothing wrong with java.util.Arrays. The designer achieves the desired effect (non-instantiability) with the necessary minimum (the private constructor).

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
0

If you want to create an immutable class or just a class that for some reason should not have childrens you should declare it as final. Private constructor should be used in utility classes, this way you block inheritance and also make sure instance of the class cannot be created.