flakes
flakes

Reputation: 23644

Effective Java: Make constructors private or package-private

From Chapter 4 of Effective Java the following example is given:

public class Complex { 
    private final double re; 
    private final double im;

    private Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }

    public static Complex valueOf(double re, double im) {
        return new Complex(re, im);
    }
    ... // Remainder unchanged
} 

[...] It is the most flexible because it allows the use of multiple package-private implementation classes. To its clients that reside outside its package, the immutable class is effectively final because it is impossible to extend a class that comes from another package and that lacks a public or protected constructor.

I understand that the class is effectively final,

but is there any actual advantage from not declaring it final?

Omitting this keyword when the class doesn't support extension seems like a less clear way to communicate how the API is meant to be used. Or was final only left out here to show the reader that non-extendable, non-final classes are possible?

Upvotes: 7

Views: 724

Answers (2)

Sleiman Jneidi
Sleiman Jneidi

Reputation: 23339

The main benefit is to limit the scope of inheritance. Declaring it final will make it sealed everywhere; however, sometimes as an author of the class you would like to inherit the class within the same package or class file but you don't want others to do the same. And that's what this trick will do.

It's a nightmare to change a class that is open for inheritance (Commonly used APIs). If you can limit the scope of inheritance, then it becomes a simple refactoring job.

Upvotes: 6

Lluis Martinez
Lluis Martinez

Reputation: 1973

This is the advantage: "... it allows the use of multiple package-private implementation classes"

If it were final, extension would be impossible (either inside or outside the package). In this way you can create another class inside the package that extends Complex (provided the constructor is package private, that is).

Upvotes: 0

Related Questions