11

I have observed that java.util.Objects has a constructor which is throwing AssertionError.

 * @since 1.7
 */
public final class Objects {
    private Objects() {
        throw new AssertionError("No java.util.Objects instances for you!");
    }
 ...

This is a static utility class and hence no instance needed.

One possible reason I understand is, the developer is trying to ensure that no instance of this class is created. As the only way anyone can call this constructor is by reflection.

Is there any other reason to have this kind of constructor?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Maas
  • 1,317
  • 9
  • 20
  • I don't know. I guess serialization? But also it sends a stronger message than just, say, saying in the Java doc that the constructor is something that should never be called. – markspace Sep 04 '14 at 06:10
  • 1
    @markspace Deserialization does not invoke constructors. – icza Sep 04 '14 at 06:11
  • 2
    What do you mean by "this kind of constructor" - what's your suggested alternative? Just having the private constructor which does nothing? – Jon Skeet Sep 04 '14 at 06:14
  • Not really, I am asking if my understand is correct about having such constructor which ensures no object of that class are created in any way possible. – Maas Sep 04 '14 at 06:16
  • Seeing this, I would indeed assume it is to protect against reflection – nablex Sep 04 '14 at 06:21
  • @icza Serialization invokes the default constructor of the nearest non-serializable base class, but this class is final and non-serializable, so Serialization doesn't apply at all. – user207421 Sep 04 '14 at 06:32
  • 1
    I love the Seinfeld reference! It's the java.util.Objects instance Nazi! – Will Hains Apr 23 '16 at 15:26

2 Answers2

16

The sole purpose is to enforce noninstantiability. Since it is private, the AssertionError is mainly for reflection and for the class itself because private constructors can be called from the class itself. And as a side effect, this idiom also prevents the class from being subclassed.

Quoting from Effective Java 2nd Edition Item 4:

// Noninstantiable utility class
public class UtilityClass {
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
    ... // Remainder omitted
}

Because the explicit constructor is private, it is inaccessible outside of the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees that the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive, as the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown above. As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.

Also you might find this Question useful:

What is the preferred Throwable to use in a private utility class constructor?

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
0

They just created this private constructor to ensure that nobody can instantiate this class. And to prevent an instantiation using reflection, the error is thrown. So I think your understanding of this construct is correct ;)

shillner
  • 1,806
  • 15
  • 24