0

I am creating an object:

public class Car {

    private ArrayList<Door> doors;
    private Engine engine;

    public Car(ArrayList<Door> doors) {
        this.doors = doors;
    }

    public Car setDoors(ArrayList<Door> doors) {
        this.doors = doors;
        return this;
    }

    public Car setEngine(Engine engine) {
        this.engine = engine;
        return this;
    }// and getters
}

Although it has public setters, is it possible to create an instance of this class and then make it immutable after creation?

Marci-man
  • 2,113
  • 3
  • 28
  • 76
  • 3
    I'd look into the builder/factory pattern and just make them immutable from the start. You could give the object an `isImmutable` flag that disables the setters, but that strikes me as hacky. – Carcigenicate May 30 '18 at 16:08
  • You can set all of its members as final. That way they can only be assigned to on construction. Of course you would have to remove your public setters but if your object is immutable they would be redundant anyway. – bhspencer May 30 '18 at 16:12

2 Answers2

1

An immutable is an unchangeable object, which means that once it's created there is no way to change its fields. Basically, you have to omit all the setters and declare fields as final. Declaring the class as final ensures that none can inherit from it.

public final class Car {

    private final List<Door> doors;
    private final Engine engine;

    public Car(final Engine engine, final List<Door> doors) {
        this.engine = engine;
        this.doors = doors;
    }

    // Getters ONLY
}

This example ensures the class is not only immutable but also constant. I highly recommend you to read an article about the Gradients of Immutability.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
0

You could check the state of the member variables and if they haven't been initialized then you can allow the setters to set the variables otherwise they will do nothing after the variables have been initialized

public class Car {

    private ArrayList<Door> doors;
    private Engine engine;

    public Car() {
        this.doors = null;
        this.engine = null;
    }

    public Car(ArrayList<Door> doors) {
        this.doors = doors;
        this.engine = null;
    }

    public Car setDoors(ArrayList<Door> doors) {
        if(this.doors == null)
            this.doors = doors;
        return this;
    }

    public Car setEngine(Engine engine) {
        if(this.engine == null)
            this.engine = engine;
        return this;
    }// and getters
}
RAZ_Muh_Taz
  • 4,059
  • 1
  • 13
  • 26