Home > Enterprise >  Java - Is this an immutable class?
Java - Is this an immutable class?

Time:09-19

I have the following class:

 public final class MyClass {
    private final int[] arr;
    private final String str;
    private final int i;

    public MyClass(int[] arr) {
        this.arr = arr;
        this.str = "abc";
        this.i = arr.length;
    }

    public String getStr() {
        return str;
    }

    public int func(int j) {
        int res = this.i   j;
        return res;
    }

}

Is this class immutable? An object is considered immutable if its state cannot change after it is constructed. In this case, all of the fields are private final, so they obviously cannot change (i.e. being reassigned) after an object is constructed. However, I could code something like this:

int[] arr = {1, 2, 3};
MyClass myClass = new MyClass(arr);

// 1
myClass.arr[0] = 100;
System.out.println(Arrays.toString(myClass.arr)); // {100, 2, 3}

// 2
myClass = new MyClass(new int[] {100, 200, 300});
System.out.println(Arrays.toString(myClass.arr)); // {100, 200, 300}

Are 1 and/or 2 considered a change of state? This question appeared on my test, and my answer was that this class is indeed immutable. The correct answer was that the constructor needs to be changed in order for this class to be immutable. An answer which I don't quite understand. Any help would be appreciated

CodePudding user response:

Because you can change the array from outside of the class, this class would not be considered immutable. However you can make it immutable by copying the array

public MyClass(int[] arr) {
    this.arr = Arrays.copyOf(arr,arr.length);
    this.str = "abc";
    this.i = arr.length;
}

CodePudding user response:

This class is mutable.

Here is example that shows it

int [] arr = {1};

MyClass x = new MyClass(arr);

x.func(0); // Will return 1

arr[0] = 2;

x.func(0); // Will return 2

To fix that you need copy array in constructor.

    public MyClass(int[] arr) {
        this.arr = new int[arr.length];
        System.arrayCopy(arr, 0, this.arr, 0, arr.length);
        this.str = "abc";
        this.i = arr.length;
    }

  • Related