views:

126

answers:

3

What is the reason why Wrapper classes (like Integer, Double, etc.) don't have a setter for their inner primitive value ?

I am asking this because that kind of functionality would have simplified calculus, and have made the Java language a little more flexible .

Let me give you some examples.

1) Let's take the following example:

Integer x = new Integer(5);
x++;

The previous code behind the scenes is performing autoboxing . Something like:

int x_tmp = x.intValue();
x_tmp++;
x = new Integer(x_tmp); // Yes that's a new memory allocation

Because of this problem doing calculus on Wrapper is slower than performing on plain primitive types. With a setter it would've been more easy to increment the inner value, without allocating another object on the heap.

2) Another issue that is bugging me is that is impossible in Java to write a swap function like I can do in C (using pointers) or in C++ (pointers or references).

If i write void swap(Integer x, Integer y) I cannot acces the inner value because, and It is going to be impossible for me to swap the values.

PS: A friend of mine suggested that i should consider the bigger picture, and think in terms of concurrency and type immutability.

So do you have an explanation for this ? Thanks!

+3  A: 

1) With a setter, the wrapper types would be mutable. Immutability is a good thing in many ways... threading, general understandability of the code etc. Personally I think it's a shame that Calendar and Date are mutable, for example.

In fact, your expansion of x++; isn't quite right - it uses Integer.valueOf which doesn't always create a new value. For example:

Integer x = 5;
x++;
Integer y = 5;
y++;

// This prints true    
System.out.println(x == y); // Compare references

Only a limited range of Integer values are cached like this (the spec defines what values must behave this way, but allows for a wider range if the JRE wishes to do so)... but it does mean that it won't always be creating a new object.

2) Yes, Java doesn't have pass by reference. Frankly I very rarely find that to be a problem. How often do you really need to swap the values of variables?

Jon Skeet
It's not about only about swapping. There are other cases when I think a problem in some way, and then I realize i have to rethink the problem.
Andrei Ciobanu
@Andrei: Usually I find that encourages me to encapsulate related values in a separate type, which is a good idea anyway. Just how often do you find yourself wanting it?
Jon Skeet
So immutability is only for protecting the "programmer" and to ease his / her work ?
Andrei Ciobanu
@Andrei: Well sort of... like encapsulation, garbage collection, polymorphism etc are "only" to make the programmer's life easier. In my experience it's a *huge* advantage in many situations.
Jon Skeet
Immutability is also to make objects thread safe
onof
+4  A: 

Wrapper classes are usually not used unless you need to put them into a collection. If they were mutable it would make problems if used inside sets and as keys for hashtables.

Sets and hashtables need the hash value to be always the same.

Christian
I guess it should've been the programmer responsibility not the language. But hey, I am just starting to learn java in a more organized way.
Andrei Ciobanu
It's not just wrapper classes: we had some issues awhile back with some non-trivial classes being used as cache keys. These classes were mutable (worse still, had ONLY default constructors) and sure enough at some point someone (well, me) re-used some keys by changing their values. The resulting bug fix included making those key classes immutable...
Rodney Gitzel
+3  A: 

Caching Integers in the range from -128 to 127 requires immutable Integers. Consider the follwoing code:

Integer id = Integer.valueOf(1);  // a new Integer, cached in Integer class

// and somewhere else

Integer key = Integer.valueOf(1);  // returns the cached value

Now if Integer was mutable and had a setter and someone did

key.setValue(2);  // not legal Java code, just for demonstration

this would change the value of id too and, to a lot of peoples surprise:

Integer one = Integer.valueOf(1);
if (one != 1)
   System.out.println("Surprise! I know, you expected `1`, but ...");
Andreas_D