File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Wrapper objects are immutable??? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Wrapper objects are immutable???" Watch "Wrapper objects are immutable???" New topic
Author

Wrapper objects are immutable???

Daniel McCracken
Greenhorn

Joined: Jul 09, 2005
Posts: 9
I've found a number of statements that a wrapper object like Integer or Double, once created, cannot be changed. You can't do:
i = new Integer(12);
i = 13;
But those lines are copied from a program than compiles and runs, and prints the value of i as 13.
I'm obviously missing something. What?
Dan McCracken

Eg, http://www.javaworld.com/javaworld/javaqa/2000-06/01-qa-0602-immutable.html and lots of others.
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809


First of all above code will compile on 1.5 not on 1.4.

At line 2, Integer literal 13 will be boxed to Integer object and same i will now refer to this new Integer object. You previous Integer object will still be in heap and eligible for GC.

Its not the same object which gets updated. Thats why they are immutable.

Immutability means their content can't be changed. You can call it final object just like final reference variable can't refer to some new Object.

Consider this exmple...



See how i++ works here..

int intPrimitive=i.intValue();
intPrimitive++;
Integer i=new Integer(intPrimitive);

So here again a new Integer object is created. Its not the same which get updated.

Hope this will help

Naseem


Asking Smart Questions FAQ - How To Put Your Code In Code Tags
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

And to make this even more concrete: "immutable" means there is no method anything like "setNewValue(int)" which changes the value represented by a given Integer object.

Sounds like the original poster would benefit from reading this and especially this.


[Jess in Action][AskingGoodQuestions]
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
At line 2, Integer literal 13 will be boxed to Integer object and same i will now refer to this new Integer object. You previous Integer object will still be in heap and eligible for GC.


Well, not quite because of a rule in the JLS about values from -128 through 128 I don't think the instance is eligible for GC at all. A later boxing to 13 would be required to box to the same instance of Integer.

Its not the same object which gets updated. Thats why they are immutable.


The reference is assigned a new value. I believe that's what you meant, but it's somewhat misleading terminology since no object is mutated to begin with whereas the sentence implies there is a mutation.

Immutability means their content can't be changed. You can call it final object just like final reference variable can't refer to some new Object.


A class that is declared final has nothing to do with mutability and isn't at all the same as declaring a variable final so I wouldn't call it a 'final object'.

Originally posted by Ernest Friedman-Hill:
And to make this even more concrete: "immutable" means there is no method anything like "setNewValue(int)" which changes the value represented by a given Integer object.


My definition (in Java):

"A class whose state cannot be mutated through methods or access to fields without using reflection."

Which pretty much means the same thing. Do you agree or disagree?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by Ken Blair:
Do you agree or disagree?


Agreed.
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809

Originally posted by Ken Blair:
Well, not quite because of a rule in the JLS about values from -128 through 128 I don't think the instance is eligible for GC at all. A later boxing to 13 would be required to box to the same instance of Integer.



Ken can you please tell me how many object will be created here..

Integer i=5;
Integer i1=(i+1);


Originally posted by Ken Blair:
A class that is declared final has nothing to do with mutability and isn't at all the same as declaring a variable final so I wouldn't call it a 'final object'.



Well I have not said anywhere if class is declared final. Then object will be immutable.

What I said is you can think of instances of Integer as a final. Their state is final. Their state can't be changed. Just like references if declared final will not be able to refer to any new instance.

I agree you can't make objects final. We don't play directly with objects so we can't make it final. It just for understanding puposes.

Naseem
[ July 11, 2006: Message edited by: Naseem Khan ]
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Naseem Khan:

Ken can you please tell me how many object will be created here..

Integer i=5;
Integer i1=(i+1);



Undefined. The Integer instances they are boxed to may or may not have already been created. The JLS requires that for values between -128 and 127 any two boxing conversions return equal references. I suppose it might be possible for an implementation to do this without literally using the same Integer instance but it's a good bet that almost all of them do. Whether or not the instance is cached eagerly or lazily and whether or not the boxing conversion has occurred before or not would be two factors affecting whether or not any object is actually created.

Originally posted by Naseem Khan:

Well I have not said anywhere if class is declared final. Then object will be immutable.



I'm not questioning your understanding so much as I am disagreeing with your use of the word 'final' because I think it's too easily confused with declaring a class final.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608

Immutability means their content can't be changed.

Immutability means that all functions of the type are referentially transparent. Referential transparency is a term that is often used in language theory, however, Java cannot prove (through the compiler) that Integer is referentially transparent and unfortunately, language theory isn't taught very well (at all?) so you rarely hear about it. Java (in fact OO) has functions - disguised as classes. To summarise the work of a 1992(?) paper - that I have forgotten the name of and will look for it - given a type X with operations O1 and parameters P1 and O2 with parameters P2, these can be written as functions:
R1 O1(X x, P1 p)
R2 O2(X X, P2 p)

It can be said then that since both O1 and O2 accept the same contract as their first parameter that they are a class of the type of the first parameter - in this case, X. Object Oriented programming simply permits a higher order communication mechanism. You and I could talk about "the X" without having to enumerate a set of functions and we would be reasonably accurate in what we were saying to each other. For example, "the String" or "the Integer". This comes at a price, however, as it digresses from a formal set of software requirements - you can observe examples in the core API. One such simple example is the Comparable and Comparator interfaces - I'll leave you to figure out what I mean exactly there.

Referential transparency denotes that a function can be invoked from its inception until its death (when the universe collapses unto itself and so time - and therefore, computational progression - ceases to exist) will behave consistently.

Looking at a concrete example: Integer.rotateLeft(int x, int y) - whcih returns say z. If it can be said that for a given x and y, that the operation will return z now and forever, the operation can also be said to be referentially transparent. The contract (written in English) states that this is true about this function and all functions of Integer, therefore, we say that it is immutable. Unfortunately, Java cannot prove this, unlike pure functional languages (where all functions are by definition - referentially transparent). This is what most people attempt to correct with things like "unit testing" (among other things), however, there is a shortfall in that an extrapolation of "it behaved like 'this' today, therefore, I extrapolate and assume that it will behave like 'this' again tomorrow" often doesn't hold. In fact, it is impossible to prove such a thing in Java, but it has led to all kinds of beefed up (potentially amusing to the agnostic observer) practices such as Test Driven Development, eXtreme Programming and "You Name It".

Unfortunately, many software development practices forget one intrinsic axiom of software - time. This may be due to industry pressure or some such; feel free to speculate, since it is fun


Tony Morris
Java Q&A (FAQ, Trivia)
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
I found the paper I referred to. Written in 1993, titled "Simple Type-Theoretic Foundations for Object-Oriented Programming" by Benjamin B. Pierce and David N. Turner.

By the way, I believe I have written this rant before, so perhaps it's time to put it somewhere that can be referred to - instead of potentially misleading readers with very common, but erroneous, definitions of "immutable".

Edit:
s/Piarce/Pierce
[ July 11, 2006: Message edited by: Tony Morris ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

A great deal of literature concerning Java's conceptual forebear C++, and a smaller amount concerning Java, take is as an axiom that a private variable can't be modified except by code in the class in which it appears. If you accept that, then formal proof of referential integrity is indeed possible for a very large set of immutable Java classes, including Java's primitive wrapper classes.

If you don't accept that, then you can't accept it for any other real language running on any other real computer, either, because there's always some metalinguistic mechanism for nondeterministic bit-twiddling; in which case, this is just navel-gazing and we're wasting our time.
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809

Undefined. The Integer instances they are boxed to may or may not have already been created. The JLS requires that for values between -128 and 127 any two boxing conversions return equal references. I suppose it might be possible for an implementation to do this without literally using the same Integer instance but it's a good bet that almost all of them do. Whether or not the instance is cached eagerly or lazily and whether or not the boxing conversion has occurred before or not would be two factors affecting whether or not any object is actually created.


SOP(i==i2) returns false.

The range -128 to 127 comes into picture if

1. Both objects are created without new.
2. Both objects have same int value.
3. Wrapper object must be of type Byte, Short or Integer.

When all the above conditions apply, then range comes into picture.

Byte b1=5;
Byte b2=6;
Both objects are not same. b1==b2 will return false.

But if..
Byte b1=5;
Byte b2=5;
Then b1==b2 will return true. Here 5 is in the range and type of b1 & b2 is Byte


Naseem
[ July 11, 2006: Message edited by: Naseem Khan ]
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Thanks Tony for the correct definition of immutability.

Regards

Naseem
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Naseem Khan:


SOP(i==i2) returns false.


i? i2? What's your point?

Originally posted by Naseem Khan:

The range -128 to 127 comes into picture if

1. Both objects are created without new.
2. Both objects have same int value.
3. Wrapper object must be of type Byte, Short or Integer.


#3 is inaccurate, but that's irrelevent, what's your point?

Originally posted by Naseem Khan:

When all the above conditions apply, then range comes into picture.

Byte b1=5;
Byte b2=6;
Both objects are not same. b1==b2 will return false.

But if..
Byte b1=5;
Byte b2=5;
Then b1==b2 will return true. Here 5 is in the range and type of b1 & b2 is Byte


Naseem


I never said otherwise. What is your point? You've yet to actually contradict anything I said.
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Hi Ken,
I don't find any reason why you are saying that the first Integer object is not eligible for garbage collection in my first code.



Can you give any reference from JLS.


#3 is inaccurate.


When you talk about this range (-128 to 127), then two Wrapper objects will be cached only if same primitive is boxed and the wrapper objects are either Byte, Short or Integer. But not Long.

Thats why I just mentioned only three wrappers.

e.g., here is no caching.

Long l1=(long)2;
Long l2=(long)2;

Two different objects will be created here.


Regards


Naseem
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Naseem]: When you talk about this range (-128 to 127), then two Wrapper objects will be cached only if same primitive is boxed and the wrapper objects are either Byte, Short or Integer. But not Long.

Not exactly. Byte, Short, and Integer are the three types that are required to cache instances in the range -128 to 127. (Character is required to cache, but only in the range 0 to 127). However it's possible for classes to cache over a wider range than they are required to. It's also possible for classes which are not required to cache at all, to cache nonetheless. Case in point: in JDK 5, look at the source code for Long.valueOf(). This class caches values from -128 to 127, exactly like Byte, Short, and Int, even though it's not required to. In another JDK you may discover they do something else entirely. You must remember that the JLS gives minimum requirements for caching, but implementations are allowed to exceed that minimum requirement.
[ July 12, 2006: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809


Yeah its mentioned on this code.

So it means, in this code, l1 and l2 will point to same Long object.

Long l1=Long.valueOf(127);
Long l2=Long.valueOf(127);

Its interesting point you have made Jim. Is this added in 1.5 onward?

Regards


Naseem
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078


Can you give any reference from JLS.
[/qb]<hr></blockquote>

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

Specifically this

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.


Note that this includes specific values of char as well as boolean literals rendering the third assertion you made inaccurate as you included neither. Furthermore, the specific range of -128 to 127 only applies to short and int, char has a different range entirely (0 to 127) and in the case of byte and boolean all values are cached.


When you talk about this range (-128 to 127), then two Wrapper objects will be cached only if same primitive is boxed and the wrapper objects are either Byte, Short or Integer. But not Long.


This is wrong, see above. Furthermore depending upon the implementation values outside of those ranges for short, int and char could be cached but it's not guaranteed. You are correct about long, however we weren't talking about a long were we? I never responded to an example that used a long.


Thats why I just mentioned only three wrappers.

e.g., here is no caching.

Long l1=(long)2;
Long l2=(long)2;

Two different objects will be created here.


I never said otherwise. That is not either of the examples I responded to is it? I responded accurately to both the examples given and to your comments about them. I'm not sure what the purpose of the continued posts are as thus far they haven't actually contradicted my responses yet the purpose seems to be to counter what I've said.

Edited for clarity.
[ July 12, 2006: Message edited by: Ken Blair ]
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Jim Yingst:
[Naseem]: When you talk about this range (-128 to 127), then two Wrapper objects will be cached only if same primitive is boxed and the wrapper objects are either Byte, Short or Integer. But not Long.

Not exactly. Byte, Short, and Integer are the three types that are required to cache instances in the range -128 to 127. (Character is required to cache, but only in the range 0 to 127). However it's possible for classes to cache over a wider range than they are required to. It's also possible for classes which are not required to cache at all, to cache nonetheless. Case in point: in JDK 5, look at the source code for Long.valueOf(). This class caches values from -128 to 127, exactly like Byte, Short, and Int, even though it's not required to. In another JDK you may discover they do something else entirely. You must remember that the JLS gives minimum requirements for caching, but implementations are allowed to exceed that minimum requirement.

[ July 12, 2006: Message edited by: Jim Yingst ]


I don't know that I'd say byte must cache only in the range -128 to 127 since, if you're representing it as a signed integer, that covers all possible values for byte. Perhaps this will clarify things:

1. For boolean, all values are cached.
2. For byte, all values are cached.
3. For char, values in the range \u0000 to \u007f must be cached. Other values may or may not be cached depending on implementation.
4. For int, values between -128 and 127 must be cached. All other values are optional.
5. For short, values between -128 and 127 must be cached. All other values are optional.
6. For long, all values are optional.
7. For float, all values are optional.
8. For double, all values are optional.

Naheem, note that none of this in any way contradicts anything I've said. Your example and the OP's example were not using long, double or float. Applying what I said to those values is taking my comments out of context. How many objects are created in the examples you have provided is undefined, period. There is absolutely no way to guarantee that any of the code posted will result in any specific number of objects being created because there is absolutely no way of determining in the examples provided whether or not the value is A) cached and B) whether or not the instance needs to be created. You should also note that as per my first response the value 13 must be cached and therefore is not likely going to be eligible for GC which is what I was pointing out.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Ken]: Note that this includes specific values of char as well as boolean literals rendering the third assertion you made inaccurate as you included neither.

If you look at Naseem's original statement, he was only talking about the conditions under which -128 to 127 are relevant. Yes, there are other cases with other ranges, and those were out of scope for what he said. (Which is why I mentioned the range for Character incidentally, not as something he was actually wrong about.) You guys seem to be talking past each other without hearing each others' words closely enough.

[Naseem]:

Long l1=(long)2;
Long l2=(long)2;

Two different objects will be created here.

[Ken]: I never said otherwise.


But I did, because in fact it's not the case, under Sun's JDK 5 at least. Two different instances may theoretically be created under some hypothetical JDK, but not by the actual JDKs that we have for JDK 1.5+. As far as I know, so far.

[Naseem]: It's interesting point you have made Jim. Is this added in 1.5 onward?

It's present in all versions of 1.5 and 1.6 that I've seen. As noted earlier, it's not guaranteed, and in the future they could do something different.
[ July 12, 2006: Message edited by: Jim Yingst ]
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
We had a couple ways to approach "immutable". To paraphrase crudely one said there are no APIs provided to change values (excluding reflection which breaks all rules) and the other said the behavior will be the same for ever and ever, amen.

Are these views both necessary? Both correct?

Would a clock be immutable? I can't change it, but the value it returns changes every millisecond.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Stan James:
We had a couple ways to approach "immutable". To paraphrase crudely one said there are no APIs provided to change values (excluding reflection which breaks all rules) and the other said the behavior will be the same for ever and ever, amen.

Are these views both necessary? Both correct?

Would a clock be immutable? I can't change it, but the value it returns changes every millisecond.


Obviously that's going to depend on what definition of "immutable" you use. Inevitably the state would be modified by a method or access to a field. Even if that was done internally it would still not fit my definition of immutable in Java. If I create an immutable class with methods that do not rely on any state outside of the class, and furthermore anything that class references for state is also immutable, then is it not referentially transparent? I think so, but that's probably because I've come to the belief that an instance of a class is nothing more than a function (ideally, although most code does not adhere to it including much of my own). If my class is immutable and I construct a new instance with state x then as far as I'm concerned that is for all intents and purposes a separate function from one constructed with state y if x != y. However, if x == y then I would expect they are identical functions and one could be substituted for the other at any time and return the exact same result.

Of course, I am hardly an expert and weak on terminology, so my opinions don't hold much weight.
Daniel McCracken
Greenhorn

Joined: Jul 09, 2005
Posts: 9
Thanks for the helpful information. Nobody was born knowing all this stuff.
Let the admitted (Java) greenhorn rephrase; is this correct?
Wrapper objects are immutable, language theory issues aside, in the same sense that strings are immutable: anytime a greenhorn might _think_ an object is being changed, what actually happens is that a new object is created.
Forgive me for posting this to the wrong forum.
Dan McCracken
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18643
    
    8

Originally posted by Daniel McCracken:
Let the admitted (Java) greenhorn rephrase; is this correct?
Wrapper objects are immutable, language theory issues aside, in the same sense that strings are immutable: anytime a greenhorn might _think_ an object is being changed, what actually happens is that a new object is created.
I wouldn't say that is correct. Certain classes in the standard API -- such as Integer, Long, and so on -- are object wrappers for primitive values. These particular classes are immutable. And that's what all the discussion in this thread has been about. But it's perfectly possible to write a wrapper class that is mutable, and it's done all the time. There's no relationship between the concepts "wrapper" and "mutable".

And to hopefully clear up the standard beginner confusion, you can only change an object by calling one of its methods. When you see an assignment being made (by the = operator), you are changing a variable. A variable cannot contain an object, it can only contain a reference to an object. If you change that variable by assigning it a reference to a different object, that does not change either of the objects involved.
Stefan Wagner
Ranch Hand

Joined: Jun 02, 2003
Posts: 1923

Originally posted by Paul Clapham:
And to hopefully clear up the standard beginner confusion, you can only change an object by calling one of its methods. When you see an assignment being made (by the = operator), you are changing a variable. A variable cannot contain an object, it can only contain a reference to an object. If you change that variable by assigning it a reference to a different object, that does not change either of the objects involved.



I don't call a method for the object, a refers to, and I can change it.
I know it's not a contradiction to what you meant, but to what you said.


http://home.arcor.de/hirnstrom/bewerbung
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Daniel McCracken:
Thanks for the helpful information. Nobody was born knowing all this stuff.

No they weren't, but it has been known since well before I was born what immutable means (and I'm nearly ready to play in the Masters comp!). All functions are referentially transparent - everything else is a spin, convolution or diversion from this very simple and accurate definition. Additional convolution comes about in the Java context since Java has no such proof of referential transparency (though I've seen some very ambitious (but doomed to fail as per mathematics) attempts).
Daniel McCracken
Greenhorn

Joined: Jul 09, 2005
Posts: 9
No they weren't, but it has been known since well before I was born what immutable means (and I'm nearly ready to play in the Masters comp!). All functions are referentially transparent - everything else is a spin, convolution or diversion from this very simple and accurate definition. Additional convolution comes about in the Java context since Java has no such proof of referential transparency (though I've seen some very ambitious (but doomed to fail as per mathematics) attempts).


Sigh. There are lots of things I don't know. One proven way to learn is to ask questions, risking sounding stupid in the process. I can handle that. I tell my students that the only stupid question is the one they don't ask. If by chance a student asks a question that goes _too_ far back into things they should have known, I talk with the student privately. I never use ridicule or sarcasm, privately or publicly. I kmow of no study demonstrating their effectiveness in teaching!

I've written a lot of elementary textbooks. In no case was I a subject matter expert. I relied heavily on a group of advisors who read everything, several times, and kept me out of the worst blunders. I praised and thanked them prominently and profusely in the preface. Well over a million people got their start in computing studying the results.

I have no plan to write an elementary Java book. I'm much too late into that game. But I'm sure not too old to try to keep our curriculum somewhere near up to date, in the courses I teach.

A forum like this is a huge help.
Dan McCracken
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Daniel McCracken:


Sigh. There are lots of things I don't know. One proven way to learn is to ask questions, risking sounding stupid in the process. I can handle that. I tell my students that the only stupid question is the one they don't ask. If by chance a student asks a question that goes _too_ far back into things they should have known, I talk with the student privately. I never use ridicule or sarcasm, privately or publicly. I kmow of no study demonstrating their effectiveness in teaching!

I hope I didn't cause you to deduce that I was ridiculing or being sarcastic. I know I come across that way at times (for which I do not apologise), but I believe that accuracy and the pursuit of knowledge transcends all other agendas in this context (such as causing warm fuzzies). Certainly, if I've made a mistake, I would prefer and appreciate someone to point it out in a way that meets only one criteria. I'll deal with any potential ego-damage another time
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Wrapper objects are immutable???