Why don't the wrapper classes for Primitives have a setter?
What is the reason why Wrapper classes (like Integer, Double, etc.) don't ha开发者_运维百科ve 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!
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.
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?
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 ...");
In Java, Strings and wrapper classes are designed as immutable to avoid accidental changes to the data. You can check the below article for further information.
Why Strings and Wrapper classes are immutable in java?
精彩评论