For example, look at this code:
Integer myInt = new Integer(5);
int i1 = myInt.intValue();
int i2 = myInt;
System.out.println(i1);
System.out.println(i2);
As you can see, I have two ways of copying my integer value from the wrapper to the primive:
I can use unboxing,
OR
I can use the method Integer#intValue().
So what's the need of having a method when there is already unboxing?
Unboxing was introduced in Java 5. The wrappers (including this method) have been there since the original release.
A link to the Javadoc
In that time (1996) we did need the intValue() method and as Oracle guarantees backward backwards compatibility... up to a certain level (it is not always 100% on major releases).
The method has to stay in.
In addition to Frank's answer which gives a good historical perspective there is still a need to use the intValue() today in some situations.
Be aware of the following pitfall that shows that you cannot regard an Integer as an int:
Integer i1 = new Integer(5);
Integer i2 = new Integer(5);
//This would be the way if they were int
System.out.println(i1 == i2); //Returns false
//This is the way for Integers
System.out.println(i1.intValue()==i2.intValue()); //Returns true
System.out.println(i1.equals(i2)); //Returns true
Returns
false
true
true
Related
import java.util.Stack;
public class StackIntro {
public static void main(String[] args){
Stack clapper = new Stack();
for( int i=0; i<11; i++){
clapper.push(i);
}
while(!clapper.isEmpty()){
System.out.print ( clapper.pop() ); //FILO
System.out.print ( ',' );
if(clapper.size()==1){
System.out.print(clapper.pop()); //FILO
System.out.println("...");
}
}
System.out.println("Lift-off.");
clapper.removeAllElements();
}
}
So basically I just wanted to see how numbers go in and out of a stack. The FILO comment shows this. I was told that I should actually change line 8 :
clapper.push(i); //previous
clapper.push(new Integer(i)); //new
I don't understand what this would accomplish, or the difference between the two.
Although due to autoboxing both lines of code result in an Integer object with value 1 being pushed on the stack, the two lines do not have exctly the same effect.
Autoboxing uses the Integer cache, which is required by the JLS for values from -128 to 127, such that the resulting Integer instance is the same instance for any value in that range.
However, invoking the int constructor creates a new Integer instance every time it's called.
Consider:
Integer a = 1; // autoboxing
Integer b = 1; // autoboxing
System.out.println(a == b); // true
Integer c = new Integer(1);
Integer d = new Integer(1);
System.out.println(c == d); // false
This distinction may cause different behaviour in your program if you use == (object identity) when comparing values pushed and popped to/from the stack instead of equals().
This would not accomplish much, very possibly not anything at all.
The idea is that clapper.push(T) accepts an object, but i is not an object, it is a primitive, so the compiler will automatically box it into an Integer object before passing it to clapper.push().
Auto-boxing was not a feature of java from the beginning, so there may still exist some old-timers who are uncomfortable with it. But that should be entirely their own problem. Java has come a long way since then. Auto-boxing is taken for granted, we do not even give it any thought anymore.
Passing i and having the compiler auto-box it is exactly the same as as passing new Integer(i).
This question already has answers here:
Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?
(8 answers)
Closed 7 years ago.
public class MainClass
{
public static void main(String[] args)
{
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4);
}
}
i1,i2,i3,i4 are not objects I guess they are only reference variables. So how they work differently from class variables?
Answer I heard is
true
false
But how? Why is it different for 127 and 128?
Since Java 5, wrapper class caching was introduced. The following is an examination of the cache created by an inner class, IntegerCache, located in the Integer cache. For example, the following code will create a cache:
Integer myNumber = 10
or
Integer myNumber = Integer.valueOf(10);
256 Integer objects are created in the range of -128 to 127 which are all stored in an Integer array. This caching functionality can be seen by looking at the inner class, IntegerCache, which is found in Integer:
So when creating an object using Integer.valueOf or directly assigning a value to an Integer within the range of -128 to 127 the same object will be returned. Therefore, consider the following example:
Integer i = 100;
Integer p = 100;
if (i == p)
System.out.println("i and p are the same.");
if (i != p)
System.out.println("i and p are different.");
if(i.equals(p))
System.out.println("i and p contain the same value.");
The output is:
i and p are the same.
i and p contain the same value.
It is important to note that object i and p only equate to true because they are the same object, the comparison is not based on the value, it is based on object equality. If Integer i and p are outside the range of -128 or 127 the cache is not used, therefore new objects are created. When doing a comparison for value always use the “.equals” method. It is also important to note that instantiating an Integer does not create this caching.
Remember that “==” is always used for object equality, it has not been overloaded for comparing unboxed values
Also see Integer wrapper objects share the same instances only within the value 127?
Integer is an object and hence the == check if the variables refer to the exact same instance. Equality of objects can be checked using the myObject.equals(otherObject)
int is the primitive type of Integer and in that case the == would return true if both the ints have the same value
update: please note that in some case, as for String for example, two variables can share the same reference depending from the code and the compiler but still it is not something you should base your code logic on.
This question already has answers here:
Integer wrapper class and == operator - where is behavior specified? [duplicate]
(2 answers)
Closed 8 years ago.
I am a novice Java programmer and came across a very weird scenario, as below.
public static void main(String[] args) {
Integer a = 500;
Integer b = 500;
// Comparing the values.
a <= b; // true
a >= b; // true
a == b; // false
// Reassigning the values
a = 50;
b = 50;
// Again comparing the values.
a <= b; // true
a >= b; // true
a == b; // true
}
My question is why do the results of a == b vary by varying values?
The answer to this question lies within the understanding of Autoboxing specified by Java programming language.
The variation in results of a == b happens because any integer between -128 to 127 are cached by the Integer class. When an int within this range is created it is retrieved from IntegerCache rather than creating a new Integer object.
Is this a bug? Of course not!
The Java class Integer is also called wrapper class because it provides an object that wraps an int primitive data type. In Java, comparing two value object is not straight forward. We should override the Object.equal method (and also the Object.hashCode) and use it to determine when two objects are equal. Using the == operator, in this case, we’re comparing the two physical object addresses. Java requires the new operator to create objects, which will be all stored on the JVM’s Heap. Local variables are stored on the JVM’s Stack, but they hold a reference to the object, not the object itself.
In first case when we check if a == b, we’re actually checking if both the references are pointing at the same location. Answer to this is NO!
But what happens when a & b are 50? To answer this we should have a look at the below Integer.valueOf method.
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
We are using the Autoboxing Java function through this Integer.valueOf method to compare a == b. With the aim of optimizing the resources use, the Integer class maintains a cache memory of Integer instances. This way, all the new Integer requests with a value between -128 and IntegerCache.high (configurable) will return an identical object allocated once. So, when we ask if a == b, we get true because, behind the scene, a and b are pointing to the same memory location.
Now another question arises: Does this approach involve in instance sharing problems? The answer fortunately is no, because Integer was defined as an immutable object and that means if you want to modify it, you have to get a new instance… exciting, isn’t it?
Shishir
Yes . Because values from a range of -127 to 128 will be stored in cache . so use equals and compare .
Java has interned the values from -128 to 127.
This is why you receive true when you compare two Integer objects in this range with ==.
If the following code is possible:
Integer a = null;
int b = a;
Does it mean that a function returning a possible null value for an integer is a bad practice?
Edit 1:
There are several different opinions in these answers. I am not enough confident to choose one or another.
That code will give a NullPointerException when you run it. It's basically equivalent to:
Integer a = null;
int b = a.intValue();
... which makes it clearer that it will indeed fail.
You're not really assigning a null value to an int - you're trying and failing.
It's fine to use null as a value for an Integer; indeed often Integer is used instead of int precisely as a "nullable equivalent`.
It is not possible. You will get NullPointerException
That will throw a NullPointerException.
The reason for this is that you're relying on auto-unboxing of the Integer value to an int primitive type. Java does this by internally calling .intValue() on the Object, which is null.
As to either it's a good practice or not... I would advise against doing so, unless the code is only used by you and you're extremely well behaved, making sure that you only assign the return value of such method to Integer values, not int.
If your code ends up in a lib used by others, it's not safe, and I would rather explicitly throw an Exception, well documented, and allow for defensive coding on the caller's part.
Funny thing with Java tenerary operator ?: (using 8u151 on OSX)
If you do
Integer x = map == null ? 0 : map.get ( key );
which seems fine and compact and all, then you get an npe!!! if
map.get ( key )
is a null. So I had to split that and it worked fine.
Of course you cannot assign null to an int. But returning a null in some situations makes sense. Null can mean that the value is not set. A typical example is a DB column.
The code is possible, but throws a NullPointerException at runtime, because of unboxing. Regarding
Does it mean that a function returning a possible null value for an
integer is a bad practice?
yes, it is. It's useless and dangerous (as you can see) to return an Integer when a int is enough, because objects can be null, while primitives can't. Integer should be used only when needed, like in a parameterized type - List<Integer>
From Java 8, we can use Optional:
// example: if an Integer object is null, an int value could receive 0, for example:
Integer value = getSomeInteger (...); // (0, null, or some other numeric value)
int inteiro = Optional.ofNullable(value).orElse(0);
That would work indeed.
Integer a = null;
Integer b = a;
But I would rather use a int value out of range (-1 if your numbers are all positive) to return in case of an error.
It's a bout Java auto-boxing.
Integer a = null;
int b = a;
this code assign a to b,actually the compiler will do this:int b=a.intValue(), so this line will throw NullPointerException;
the code :
Integer a = 1;
will actually do this: Integer a = Integer.valueOf(1);
You can use javap to see the compiled virtual machine instructions。
You can write simple test:
public class Test {
public static void main(String[] args){
Integer a = null;
int b = a;
System.out.println(b);
}
}
And the output is a NullPointerException on int b = a;
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
What is the difference between them?
l is an arraylist of Integer type.
version 1:
int[] a = new int[l.size()];
for (int i = 0; i < l.size(); i++) {
a[i] = l.get(i);
}
return a;
version 2:
int[] a = new int[l.size()];
for (int i = 0; i < l.size(); i++) {
a[i] = l.get(i).intValue();
}
return a;
l.get(i); will return Integer and then calling intValue(); on it will return the integer as type int.
Converting an int to Integer is called boxing.
Converting an Integer to int is called unboxing
And so on for conversion between other primitive types and their corresponding Wrapper classes.
Since java 5, it will automatically do the required conversions for you(autoboxing), so there is no difference in your examples if you are working with Java 5 or later. The only thing you have to look after is if an Integer is null, and you directly assign it to int then it will throw NullPointerException.
Prior to java 5, the programmer himself had to do boxing/unboxing.
As you noticed, intValue is not of much use when you already know you have an Integer. However, this method is not declared in Integer, but in the general Number class. In a situation where all you know is that you have some Number, you'll realize the utility of that method.
The Object returned by l.get(i) is an instance of the Integer class.
intValue() is a instance method of the Integer class that returns a primitive int.
See Java reference doc...
http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html#intValue()
Java support two types of structures first are primitives, second are Objects.
Method that you are asking, is used to retrieve value from Object to primitive.
All java types that represent number extend class Number. This methods are in someway deprecated if you use same primitive and object type since [autoboxing] was implemented in Java 1.5.
int - primitive
Integer - object
Before Java 1.5 we was force to write
int i = integer.intValue();
since Java 1.5 we can write
int i = integer;
Those methods are also used when we need to change our type from Integer to long
long l = integer.longValue();
Consider this example:
Integer i = new Integer(10);
Integer j = new Integer(10);
if (!(i == j)) {
System.out.println("Surprise, doesn't match!");
}
if (i.intValue() == j.intValue()) {
System.out.println("Cool, matches now!");
}
which prints
Surprise, doesn't match!
Cool, matches now!
That proves that intValue() is of great relevance. More so because Java does not allow to store primitive types directly into the containers, and very often we need to compare the values stored in them. For example:
oneStack.peek() == anotherStack.peek()
doesn't work the way we usually expects it to work, while the below statement does the job, much like a workaround:
oneStack.peek().intValue() == anotherStack.peek().intValue()
get(i) will return Integer object and will get its value when you call intValue().In first case, automatically auto-unboxing happens.
They are exactly the same. As other posters have mentioned, you can put either the Integer object or the int primitive into the array. In the first case, the compiler will automatically convert the Integer object into a primitive. This is called auto-boxing.
It's just a convenience method for getting primitive value from object of Number: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Number.html
Consider the code:
Integer integerValue = Integer.valueOf(123);
float floatValue = integerValue.floatValue();
The last line is a convenient method to do:
float floatValue = (float)(int)integerValue;
Since any numeric type in Java can be explicitly cast to any other primitive numeric type, Number class implements all these conversions. As usual, some of them don't make much sense:
Integer integerValue = Integer.valueOf(123);
int intValue = integerValue.intValue();
int intValue2 = (int)integerValue;
int intValue3 = integerValue;