1

I tried to make the instance variable in the following class immutable by making it final..But it seems that I can modify its data.. Is only the reference immutable? (ie I cannot assign another instance of Y to that variable?)

public class StateModification {
    private final Y immutable ;


    public StateModification() {
        super();
        this.immutable = new Y(100);
    }
    public void setImmutableData(int x){
        this.immutable.setYnum(x);
    }

    public int getImmutableData(){
        return this.immutable.getYnum();
    }


    public static void main(String[] args) {
        StateModification sm = new StateModification();

        System.out.println("immutable="+sm.getImmutableData());
        sm.setImmutableData(222);
        System.out.println("immutable="+sm.getImmutableData());
    }
}

class Y{
    private int ynum;
    public Y(int ynum) {
        super();
        this.ynum = ynum;
    }

    public int getYnum() {
        return ynum;
    }

    public void setYnum(int ynum) {
        this.ynum = ynum;
    }
}

o/p

immutable=100
immutable=222

damon
  • 8,127
  • 17
  • 69
  • 114
  • 8
    "*Is only the reference immutable?*" => Yes that's it. – assylias Jun 12 '13 at 14:11
  • 1
    @assylias you should post that as an answer, even if it's so short. – Joeri Hendrickx Jun 12 '13 at 14:12
  • `final` has little to nothing to do with immutability. – Brian Roach Jun 12 '13 at 14:14
  • @BrianRoach That is maybe a little too strong a statement! – assylias Jun 12 '13 at 14:15
  • @assylias - How so? An immutable object needs not use the keyword `final` at all unless you don't want anyone to extend it. – Brian Roach Jun 12 '13 at 14:16
  • 1
    @BrianRoach It does, otherwise it is only effectively immutable, which makes a difference from a memory model's perspective (I'm referring here to the fields being final, not the class itself, which is more of a security issue). – assylias Jun 12 '13 at 14:17
  • If I can't change the data contained within because it's *effectively* immutable, I am completely fine with calling it immutable ;) And given that you can change `final` fields through reflection unless you set up a SecurityManager ... then *everything* is "effectively" immutable. (While I *do* use `final` in my classes I'm merely pointing out that it's not necessary from a conceptual standpoint) – Brian Roach Jun 12 '13 at 14:21
  • @BrianRoach http://stackoverflow.com/a/16061087/829571 – assylias Jun 12 '13 at 14:25
  • @assylias - Fair point - I didn't understand that's what you were getting at with the term "effective" (Ireplied before you edited your comment). That said, you get the same guarantee from `volatile` if you want to talk about the thread caching. – Brian Roach Jun 12 '13 at 14:29

4 Answers4

2

This:

private final Y immutable

means only the reference is immutable. The fields of Y should be immutable too. Note that suitable encapsulation can provide immutability as well as/instead of finalising the references. That will help you as/when you adopt mutable classes as members.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
2

The problem here has a recursive nature. If all your classes are immutable, you don't have any problem with reference types. But if there are some classes that are not immutable and you have to use then as private fields, there is no way to make them immutable, afaik.

BTW. using reflection, you can modify even the state of an instance of an immutable class.

Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72
0

Yes.True.When you have a reference to an instance of an object, the contents of that instance can be altered.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • This doesn't really make sense. You answer yes which is correct, but then you say *the contents of that instance cannot be altered* which is wrong. The `Y` class is the instance and the content can be changed. – maba Jun 12 '13 at 14:19
  • Oops ..thanks for the spot dudes.Edited :) – Suresh Atta Jun 12 '13 at 14:36
0

Yes. By making immutable final only the immutable variable will be affected (the final behavior is not inherited/propagated to the object fields). If you would like the ynum to be unchanged once it's value is set you should make that final too.

dan
  • 13,132
  • 3
  • 38
  • 49