2

I'm confused about Type wrappers being immutable when executing following code

static void inc(Integer nr)
{
    System.out.printf("1. inc() \t %d \n", nr);
    nr++;
    System.out.printf("2. inc() \t %d \n", nr);
} // inc()

public static void main(String[] args)
{
    Integer nr1 = 10;
    System.out.printf("a. main() \t %d \n", nr1);
    inc(nr1);
    System.out.printf("b. main() \t %d \n", nr1);
} // main()

Executing it creates following output

  a. main()     10 
  1. inc()      10 
  2. inc()      11 
  b. main()     10 

If a type wrapper is immutable, why then is the value increased between line "1. inc" and "2. inc" and does line "b. main" print the same value as "1. main"?

thank you

Chris

Chris
  • 117
  • 1
  • 5

1 Answers1

2

If a type wrapper is immutable, why then is the value increased between line "1. inc" and "2. inc"

Because you're not actually mutating the existing Integer object - you're creating a new one (well, effectively - actually it'll use common cached objects, but the point is that the value of nr will refer to a different object after nr++). Think of this:

nr++;

As instead:

int tmp = nr.intValue();
tmp++;
nr = Integer.valueOf(tmp);

So the fact that you see the text representation of nr changing doesn't mean that the object it refers to has mutated - in this case, the cause is that nr itself has taken on a new value, referring to a different object.

You can see that with more diagnostics, too:

static void inc(Integer nr)
{
    Integer original = nr;
    System.out.printf("1. inc() \t %d \n", nr);
    nr++;
    System.out.printf("2. inc() \t %d \n", nr);
    // This will print 10
    System.out.printf("Original: %d\n", original);
} 

and does line "b. main" print the same value as "1. main"?

The reference is passed by value, just as it always is. That means inc(nr1) doesn't modify nr1 at all - it refers to the same object it did before. As I said above, inc also doesn't modify the object (because the wrapper types are immutable). Therefore after the call, nr1 refers to the same object wrapping the same value (10).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • The OP also wants to know why the value of an immutable object changes when post-incremented. – Chetan Kinger Jun 19 '15 at 15:34
  • @ChetanKinger: It doesn't. That's the point. I've explained both parts that the OP has asked about, as far as I can see... – Jon Skeet Jun 19 '15 at 15:35
  • @ChetanKinger as the answer says, it doesn't. – Samuel Edwin Ward Jun 19 '15 at 15:37
  • @JonSkeet My bad. The answer is implied. – Chetan Kinger Jun 19 '15 at 15:37
  • @ChetanKinger: I think it's pretty explicit, actually. I've expanded it more. Of course, you can write your own answer if you think mine isn't clear enough. – Jon Skeet Jun 19 '15 at 15:37
  • I think, the part with the `tmp` variable is rather confusing. It’s better to emphasize that `nr++;` is just a short-hand for `nr = nr + 1;` here, which is just a short-hand for `nr = Integer.valueOf(nr.intValue() + 1);`; there is no temporary variable involved… – Holger Jun 19 '15 at 15:43
  • @Holger: I disagree - I think it's clearer to show one simple expression per line. Given that the intermediate expression effective *is* a temporary variable, I think it's entirely reasonable to break it down all the way. – Jon Skeet Jun 19 '15 at 15:45
  • Intermediate expressions *are not* temporary variables. That’s the point. Otherwise, by writing `tmp++;`, which is again a short-hand for `tmp = tmp + 1;` you would create another temporary variable. – Holger Jun 19 '15 at 15:49
  • @Holger: I view them as *effectively* equivalent to temporary variables. I personally view three statements each of which does one thing as simpler than one statement which does three things. But as I said to Chetan - if you think you have a clearer way of explaining it, add your own answer. I'm not going to change *my* answer to an explanation which *I* feel is less clear. – Jon Skeet Jun 19 '15 at 15:53
  • @JonSkeet I chose to ignore your first comment which said *Of course, you can write your own answer if you think mine isn't clear enough* because I assumed you might have overlooked the fact that the question is closed. Your second comment *if you think you have a clearer way of explaining it, add your own answer. I'm not going to change my answer to an explanation which I feel is less clear* is a bit out of line because none is asking you to change your answer but simply letting you know that it's confusing to others. – Chetan Kinger Jun 19 '15 at 16:09
  • @Chetan: I had indeed overlooked that it is closed. But I still personally feel this is the clearest I can express it, and that the suggested changes would make the answer worse - therefore I will not be applying them. – Jon Skeet Jun 19 '15 at 16:10
  • @JonSkeet Your discussion with Holger is on a different aspect of your answer than the one you are having with me so let's not mix them. The question is a two part question. 1. Why does the value of an immutable object get incremented? 2. Why does the value of an immutable object remain the same when passed to a method? Your answer before your edit did not explain part 1 i.e, why does the value of the immutable object `nr` get incremented inside the `inc` method so that the second `print` statement in `inc` printed `11`. Part 1 may have been implied by Part 2 but in the most indirect way. – Chetan Kinger Jun 19 '15 at 16:24
  • @ChetanKinger: Again, we'll have to agree to disagree. I think revision 1 already answered part 1, although it's clearer now. Anyway, I don't think this conversation is adding any value at this point... – Jon Skeet Jun 19 '15 at 16:27
  • @ChetanKinger You (or the OP if you're asking on behalf of them) will need to differentiate between object, reference, and variable. – Sotirios Delimanolis Jun 19 '15 at 16:31