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!
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?
Related
I know in Java, there are three different ways below to transform the primitive types to their corresponding wrapper classes. However, is there any preferred way if performance is critical ?
Integer i = new Integer(5);
Integer i = 5;
Integer i = Integer.valueOf(5);
The javadocs for Integer.valueOf(int) emit a pretty clear recommendation:
If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
And as pointed out by Pshemo in the comments, and as considered in this SO thread, Integer i = 5; essentially gets converted automatically to Integer i = Integer.valueOf(5);. So using either won't make a difference performance-wise.
So if performance is a concern, simply avoid using new Integer(5) to benefit from the caching.
I know the usual reasons that apply to general immutable classes, viz
can not change as a side effect
easy to reason about their state
inherently thread safe
no need to provide clone/copy constructor/factory copy method
instance caching
no need for defensive copies.
However, wrapper classes represent primitive types, and primitive types are mutable. So why aren't wrapper classes mutable?
However, wrapper classes represent primitive types, and primitive types (except String) are mutable.
Firstly, String isn't a primitive type.
Secondly, it makes no sense to talk about the primitive types being mutable. If you change the value of a variable like this:
int x = 5;
x = 6;
That's not changing the number 5 - it's changing the value of x.
While the wrapper types could have been made mutable, it would have been annoying to do so, in my view. I frequently use readonly collections of these types, and wouldn't want them to be changeable. Very occasionally I want a mutable equivalent, but in that case it's easy enough to come up with one, or use the Atomic* classes.
I find myself wishing that Date and Calendar were immutable far more often than I find myself wanting Integer to be mutable... (Of course I normally reach for Joda Time instead, but one of the benefits of Joda Time is immutability.)
There are mutable, thread safe wrappers as well for some types.
AtomicBoolean
AtomicInteger
AtomicIntegerArray
AtomicLong
AtomicLongArray
AtomicReference - can wrap a String.
AtomicReferenceArray
Plus some exotic wrappers
AtomicMarkableReference - A reference and boolean
AtomicStampedReference - A reference and int
Here is an example where it would be quite bad when Integer would be mutable
class Foo{
private Integer value;
public set(Integer value) { this.value = value; }
}
/* ... */
Foo foo1 = new Foo();
Foo foo2 = new Foo();
Foo foo3 = new Foo();
Integer i = new Integer(1);
foo1.set(i);
++i;
foo2.set(i);
++i;
foo3.set(i);
Which are the values of foo1, foo2 and foo3 now? You would expect them to be 1, 2 and 3. But when Integer would be mutable, they would now all be 3 because Foo.value would all point to the same Integer object.
For your info: if you want mutable holder classes, you can use the Atomic* classes in the java.util.concurrent package, e.g. AtomicInteger, AtomicLong
The wrapper classes are immutable because it just makes no sense to be mutable.
Consider following code:
int n = 5;
n = 6;
Integer N = new Integer(n);
At first, it looks straightforward if you can change the value of N,
just like you can change the value of n.
But actually N is not a wrapper to n, but a wrapper to 6!
Look at the following line again:
Integer N = new Integer(n);
You are actually passing the value of n, which is 6, to N.
And since Java is pass-by-value, you cannot pass n into N,
to make N a wrapper to n.
So, if we did add a set method to the wrapper:
Integer N = new Integer(n);
N.setValue(7);
print(N); // ok, now it is 7
print(n); // oops, still 6!
The value of n will not be changed and that will be confusing!
Conclusion:
wrapper classes are wrappers of values, not wrappers of the variables.
it will be confusing if you did add a set method.
if you know it is a wrapper of a value, you will no longer ask for a set method. For example, you will not do "6.setValue(7)".
it's impossible to make a wrapper to a variable in Java.
However, wrapper classes represent primitive types, and primitive types (except String) are mutable.
No they're not (and String isn't a primitive type). But since primitive types aren't objects anyway, they can't really be called mutable / immutable in the first place.
Regardless, the fact that wrapper classes are immutable is a design decision (a good one IMO.) They could have just has easily been made mutable, or mutable alternatives provided too (indeed several libraries provide this, and other languages do by default.)
Any object instance which has any mutable aspects must have a unique identity; otherwise, another object instances which at one moment happened to be identical in every way except for its identity might at some other moment be different in its mutable aspect. In many cases, though, it's useful for types not to have an identity--to be able to pass a "4" without having to worry about which "4" one is passing. While there are times when it may be helpful to have a mutable wrapper of a primitive or immutable type, there are many more times when it's useful to have a type where all instances that hold the same data at some moment in time may be regarded as interchangeable.
The primitive types are mutable, but they are not shareable - that is no two sections of code will ever be referring to the same int variable (they are always passed by value). So you can change your copy and no one else sees the change, and vice versa. As Phillip shows in his answer, that would not be the case with mutable wrapper classes. So my guess is that they had a choice when the wrapped the primitive data types between:
matching the fact that you can change the value of a primitive type,
versus
matching the fact that primitive types can be passed around and no changes by a user will be seen by any other user of the data.
And they chose the latter, which required immutability.
For example, consider the following java program:
class WhyMutable
{
public static void main(String[] args)
{
String name = "Vipin";
Double sal = 60000.00;
displayTax(name, sal);
}
static void displayTax(String name, Double num) {
name = "Hello " + name.concat("!");
num = num * 30 / 100;
System.out.println(name + " You have to pay tax $" + num);
}
}
Result: Hello Vipin! You have to pay tax $18000.0
This is the case with pass by reference of wrapper class parameters as well. And, if strings and wrapper classes are non-final, anybody can extend those classes and write their own code to modify the wrapped primitive data. So, in order to maintain Data Integrity, the variables which we are using for data storage must be read-only,
i.e., Strings and Wrapper classes must be final & immutable and “pass
by reference” feature should not be provided.
Read this on the oracle docs java.lang page:
Frequently it is necessary to represent a value of primitive type as if it were an object. The wrapper classes Boolean, Character, Integer, Long, Float, and Double serve this purpose.
I'm not sure I understand why these are needed. It says they have useful functions such as equals(). But if I can do (a==b), why would I ever want to declare them as Integer, use more memory and use equals()? How does the memory usage differ for the 2?
Java's generics system only supports class types. And since primitives are not classes, they can't be used with generics. However, a primitive's wrapper class can be used as a generic type. For example, you may not declare an ArrayList<int>, but you can achieve a similar functionality with an ArrayList<Integer>.
It is also of occasional use to initialize a variable's value to null. Primitives, however, cannot be set to null; that privilege is reserved for objects.
// This is OK
Integer iDontKnowValueYet = null;
// Compile error!
int iDontKnowThisYetEither = null;
Things like int, char, double are all primitives meaning they do not need to be instantiated by using "new". Things like Integer, Character, Double are objects that take up more room on the computer (since there is more overhead for objects) but you can use methods like Integer.parse(). In general, use the primitives and only use the object versions if you need one of the methods.
To answer the thing about a==b vs a.equals(b):
Integer a = new Integer(5);
Integer b = new Integer(5);
Even though they are the same value (which is what .equals tests for) they are not the same piece of memory since you said "new" twice. a!=b but a.equals(b)
Integer a = new Integer(5);
Integer b = a;
Now they use the same piece of memory meaning if you change one, you change them both (unless you use "new" again). a==b and a.equals(b)
//using last code block
b = new Integer(5);
Now once again a!=b but a.equals(b)==true since once again they have the same value but they are on different pieces of memory.
Your ints are usually wrapped in wrapper classes when you put them in a data structure. So, .equals method is used to determine when you call .contains method on the data structure.
Other usefule methods:
toString
toHexString
parseString
How can I store the address of one object or variable in another object in Java. Like we do in C++
int a=&b; // b is also int
If I want to pass reference type objects by reference in Java to any method, how can I do this cuz by default they are passed by value.
You can't, basically. Everything is passed by value in Java, and there's no way of changing that.
The closest you can come is to create your own generic mutable wrapper type, or use an array of length 1. The wrapper approach makes it much clearer what you're doing, but it's less efficient. You can use AtomicReference<V> as a wrapper type if you want, although its use implies that you're concerned about concurrency when you probably aren't.
For wrappers of primitive types, you could either use the Integer, Long etc classes, or you could write an individual specific wrapper type for each primitive. (Again, the latter would be slightly more efficient.)
Fundamentally though, you should try to design your code not to need this. I very rarely find it a useful technique. If you find yourself wanting to do it very often, you may be "thinking" in a different language...
You can not use addresses in Java. There is simply no such ability. All things are passed by value. When you want to pass an object to be mutated you have several ways:
a) Pass an array:
int [] valueArray = new int[1];
valueArray[0] = <your value>;
b) Pass a mutable wrapper, which you shoud write by your self.
c) Pass an input int and retur a new value:
int a = 5;
a = sqr(a);
There comes a difference from C++ to java. Even though it's not a good practice to use the address of an Object in java, there are ways to get the logical address.
http://javapapers.com/core-java/address-of-a-java-object/
I hope this will help you.
In which case should you use primitive types(int) or reference types (Integer)?
This question sparked my curiosity.
In which case should you use primitive
types(int) or reference types
(Integer)?
As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.
One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:
List<int> intList = new ArrayList<int>(); // Not allowed.
List<Integer> integerList = new ArrayList<Integer>(); // Allowed.
And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:
// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3);
int sum = 0;
// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
sum += number;
}
Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:
Integer i1 = Integer.valueOf(1); // Prefer this.
Integer i2 = new Integer(1); // Avoid if not necessary.
For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.
That really depends on the context. First prefer the primitive, because it's more intuitive and has less overhead. If it is not possible for generics/autoboxing reasons, or if you want it to be nullable, then go for the wrapper type (complex type as you call it).
The general rules I follow when creating an API can be summarized as follows:
If the method must return an value, use a primitive type
If the method may not always apply (eg: getRadioId(...) on an object where such an ID may not exist), then return an Integer and specify in the JavaDocs that the method will return null in some cases.
On #2, look out for NPEs when autoboxing. If you have a method defined as:
public Integer getValue();
And then call it as follows:
int myValue = getValue();
In the case where getValue() returns null you'll get an NPE without an obvious cause.
Since Java does something called auto-boxing and auto-unboxing, you should use the primitive type int in most cases because of less overhead.
The only time you absolutely need to use Integer is in generics.
List<int> list; // won't compile
List<Integer> list; // correct
One case in which Integer might be prefered is when you are working with a database where numerical entries are allowed to be null, since you wouldn't be able to represent a null value with an int.
But of course if you're doing straight math, then int would be better as others have mentioned due to intuitiveness and less overhead.
My rule of thumb is: use boxed primitives only when it's necessary to get the code to compile. The only places in your code where the names of the primitive wrapper classes should appear is in generic type parameters and static method calls:
List<Integer> intList = new ArrayList<Integer>();
int n = Integer.parseInt("123");
That's the advice I would give to new Java programmers. As they learn more, they'll run into situations where they have to be more discerning, like when dealing with Maps or databases, but by then they should also have a better understanding of the difference between primitives and boxed primitives.
Autoboxing tempts us to believe int and Integer (for example) are interchangeable, but it's a trap. If you mix the two kinds of value indiscriminately, you can end up comparing two Integer values with == or trying to unbox a null without realizing it. The resulting bugs can be intermittent and difficult to track down.
It doesn't help that comparing boxed primitives with == sometimes works as if it were doing a value comparison. It's an illusion caused by the fact that values within a certain range are automatically cached in the process of autoboxing. It's the same problem we've always had with String values: comparing them with == sometimes "works" because you're actually comparing two references to the same, cached object.
When dealing with strings we can just tell the n00bs never to compare them with ==, as we've been doing all along. But comparing primitives with == is perfectly valid; the trick (thanks to autoboxing) is being sure the values really are primitives. The compiler will now let us declare a variable as an Integer and use it as if it were an int; that means we have to exercise a greater level of discipline and treat it as an error when someone does so without good reason.
Rather than calling them "complex types", you'd be best served thinking Integer, Double, etc. as "Classes", and int, double, etc. as "primitives".
If you're doing any type of sophisticated math, the Class-based numeric representation like Integer and Double will be cumbersome and slow you down - many math operations can only be done with primitives.
On the other hand, if you're trying to put your numbers into collections like Lists and Maps, those collections can only contain objects - and thus you must use (or convert to) classes like Integer and Double.
Personally, I use primitives whenever I can get away with it, and only convert to the Class representations like Integer when it's time to do input or output, and the transport requires those representations.
However, if you aren't doing any math at all, and instead are just passing the values straight through your code, you might save yourself some trouble by dealing with the Class-based forms (like Integer) exclusively.
I think this is a bit late but I wanted to add my opinion just in case.
in some scenarios, it's required to use the wrappers as the lack of a value is different from the default value.
example,
for one project I worked on, there was a field on screen where the user could enter a double value, the business requirement clearly mentioned that if the user enters a 0 the meaning is different from not entering a value and leaving the field blank and this difference will make an impact later on in a different module.
so in this scenario we had to use the Double object, since I cannot represent a lack of value using the primitive; since the primitive will default to 0 which was a valid input for the field.
I dont think there is any rule as such. I would choose the types over primitives (Integer over int) when I write method signatures, Maps, collections, Data Objects that get passed around. As such I would still like to use Integer instead of int even inside of methods etc. But if you think that is too much trouble (to type extra "eger") then it is okay to use ints for local variables.
If you want to setAttribute to session you have to use Object like Integer,Boolean,String in servlets. If you want to use value you can use primitive types. Objects may be null but primitives not. And if you want to compare types for primitives use == but objects use .equals because in object comparision == looks not values it looks if these are the same objects. And using primitives makes faster the code.
When we deal with Spring getRequest mapping methods, using boolean value does not work.
For instance :
#GetMapping("/goal")
public boolean isValidGoal() {
boolean isValid = true;
return isValid;
}
Always opt for Boolean in those cases.