Differences between new Integer(123), Integer.valueOf(123) and just 123 - java

Recenlty I saw code (Java) like this:
myMethod(new Integer(123));
I am currently refactoring some code, and there is a tip in Sonar tool, that it's more memory friendly to use sth like this:
myMethod(Integer.valueOf(123));
However in this case, I think that there is no difference if I would use:
myMethod(123);
I could understand that, if I would pass a variable to the method, but hard coded int? Or if there would be Long/Double etc and I want Long representation of number. But integer?

new Integer(123) will create a new Object instance for each call.
According to the javadoc, Integer.valueOf(123) has the difference it caches Objects... so you may (or may not) end up with the same Object if you call it more than once.
For instance, the following code:
public static void main(String[] args) {
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println("a==b? " + (a==b));
Integer c = Integer.valueOf(1);
Integer d = Integer.valueOf(1);
System.out.println("c==d? " + (c==d));
}
Has the following output:
a==b? false
c==d? true
As to using the int value, you are using the primitive type (considering your method also uses the primitive type on its signature) - it will use slightly less memory and might be faster, but you won't be ale to add it to collections, for instance.
Also take a look at Java's AutoBoxing if your method's signature uses Integer- when using it, the JVM will automatically call Integer.valueOf() for you (therefore using the cache aswell).

public static Integer valueOf(int i)
Returns a Integer instance representing the specified int value. 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.
Parameters:
i - an int value.
Returns:
a Integer instance representing i.
Since:
1.5
refer http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29
This variant of valueOf was added in JDK 5 to Byte, Short, Integer, and Long (it already existed in the trivial case in Boolean since JDK 1.4). All of these are, of course, immutable objects in Java. Used to be that if you needed an Integer object from an int, you’d construct a new Integer. But in JDK 5+, you should really use valueOf because Integer now caches Integer objects between -128 and 127 and can hand you back the same exact Integer(0) object every time instead of wasting an object construction on a brand new identical Integer object.
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
refer Why YOU should use Integer.valueOf(int)
EDIT
autoboxing and object creation:
The important point we must consider is that autoboxing doesn't reduce object creation, but it reduces code complexity. A good rule of thumb is to use primitive types where there is no need for objects, for two reasons:
Primitive types will not be slower than their corresponding wrapper types, and may be a lot faster.
There can be some unexpected behavior involving == (compare references) and .equals() (compare values).
Normally, when the primitive types are boxed into the wrapper types, the JVM allocates memory and creates a new object. But for some special cases, the JVM reuses the same object.
The following is the list of primitives stored as immutable objects:
boolean values true and false
All byte values
short values between -128 and 127
int values between -128 and 127
char in the range \u0000 to \u007F
refer http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance_issue

only range between -128 to +127 implements in cache.
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println("a==b? " + (a==b));
Integer c = Integer.valueOf(127);
Integer d = Integer.valueOf(127);
System.out.println("c==d? " + (c==d));
Integer e = Integer.valueOf(128);
Integer f = Integer.valueOf(128);
System.out.println("e==f? " + (e==f));
Refer this java specification:
http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7
in JDK 5+, you should really use valueOf because Integer now caches Integer objects between -128 and 127 and can hand you back the same exact Integer(0) object every time instead of wasting an object construction on a brand new identical Integer object.

int is primitive type, not an object.
new Integer(123) and Integer.valueOf(123) both return Integer object representing value 123. As per javadoc for Integer.valueOf():
Returns a Integer instance representing the specified int value.
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.

Does your method require an int or an Integer?
new Integer(int) and Integer.valueOf(int) both return Integer objects, but valueOf should be preferred as it is more efficient because it returns cached objects. If your method requires an Integer you should use Integer.valueOf.
If your method requires an int, you should use an int (e.g. 123).
However, it is not strictly necessary to match types in this way because of autoboxing, which automatically converts an int to an Integer and vice versa when the types don't match. This allows you to pass an int into a method requiring an Integer, and an Integer into a method requiring an int. But be aware that there are performance costs associated with autoboxing. The most common example of when you would use autoboxing is if you wanted to store primitives in a collection.

When you use some thing like new Integer(88) the SpotBugs code analyze tool, complains a performance issue.
The description of this issue shows deference of new and valueOf
Method invokes inefficient Number constructor; use static valueOf
instead Using new Integer(int) is guaranteed to always result in a new
object whereas Integer.valueOf(int) allows caching of values to be
done by the compiler, class library, or JVM. Using of cached values
avoids object allocation and the code will be faster. Values between
-128 and 127 are guaranteed to have corresponding cached instances and using valueOf is approximately 3.5 times faster than using
constructor. For values outside the constant range the performance of
both styles is the same. Unless the class must be compatible with JVMs
predating Java 5, use either autoboxing or the valueOf() method when
creating instances of Long, Integer, Short, Character, and Byte. Bug
kind and pattern: Bx - DM_NUMBER_CTOR

Related

Any chance of Object auto casting to Integer?

I am wondering whether the below code should work in any scenario?
Object value = attValue.getValue(); // Returns an Object, might contain an Integer
if (value instanceof Integer) {
if (mAccount.getValue() != value) { // mAccount.getValue() return int
// Do something here
}
}
It works in my Android studio but not in some other's PC. What is making it work for me?
Yes, that's entirely feasible given the way autoboxing is guaranteed to work on small values, and is permitted to work on larger values. For example, this is guaranteed to print true:
Object x = 5;
Object y = 5;
System.out.println(x == y);
This might print true, but isn't guaranteed to:
Object x = 10000;
Object y = 10000;
System.out.println(x == y);
I would definitely try not to rely on this in code though, partly because while values in the range of -128 to 127 inclusive are guaranteed to be reused (see JLS 5.1.7), the fact that some JVMs may reuse a wider range of values could lead you into a false sense of security about your code.
In your case, we don't know whether you're seeing a difference in platforms (also bearing in mind that we're talking about Android rather than a JVM) or just that when it "worked" the value being boxed was small, and when it "didn't work" it wasn't.
You're getting the same Integer instance, since Java 5 there has been an Integer Cache. Because of that cache, you get the same Integer reference (you're getting the same Integer reference, and because it's the same reference they have reference identity - which is what == tests). The linked Integer cache document says (in part)
Integer objects are cached internally and reused via the same referenced objects.
This is applicable for Integer values in range between –127 to +127 (Max Integer value).
This Integer caching works only on autoboxing. Integer objects will not be cached when they are built using the constructor.

If int does not inherit Object, then why does "String.format(String, Object ...)" compile with int's?

I read this post: Is int an object in Java?.
In the post it is argued that int is not inherited from Object. If so is the case, then why does the code below compile without any error? Given that int is not Object and the signature of format() method is public static String format(String format, Object... args) as shown in documentation: javadoc for String!
public class Testing {
public static void main(String[] args) {
int integer = 7;
String str = String.format("%03d", integer);
System.out.println(str);
}
}
I have also read about "Autoboxing". What does this exactly mean? Are all the primitives replaced by appropriate Object's before compilation? If so, then is there any advantage of memory usage while using large array of int's (int[]) over Integer's (Integer[])? Similar arguments follow for double's etc.
Any insights are welcome.
It is caused by Autoboxing.
Here is a small snippet from the linked Java documentation that explains it better than I could:
Autoboxing is the automatic conversion that the Java compiler makes
between the primitive types and their corresponding object wrapper
classes. For example, converting an int to an Integer, a double to a
Double, and so on. If the conversion goes the other way, this is
called unboxing.
Here is the simplest example of autoboxing:
Character ch = 'a';
The rest of the examples in this section use generics. If you are not
yet familiar with the syntax of generics, see the Generics (Updated)
lesson.
Consider the following code:
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(i);
Although you add the int values as primitive types, rather than
Integer objects, to li, the code compiles. Because li is a list of
Integer objects, not a list of int values, you may wonder why the Java
compiler does not issue a compile-time error. The compiler does not
generate an error because it creates an Integer object from i and adds
the object to li. Thus, the compiler converts the previous code to the
following at runtime:
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(Integer.valueOf(i));
When calling String.format("%d",myInt), myInt is automatically (and implicitly) wrapped in an Integer instance, which extends Object, therefore it compiles.
Concerning the arrays, the conversion from primitiveType[] to WrapperClass[] is not automatic for some reason. If you try to use an array of a primitive type where an array of the wrapper class is expected, it will result in a compile error.
Using Integer creates an overhead compared to using int because you need to assign and store references. However, this overhead is limited when using Integer values between -128 and 127 because these values are pooled (which means that all instances of Integer wrapping a value in this in interval point to a unic reference).
Autoboxing is a help from the compiler, which automatically compiles something like
foo(i);
into
foo(Integer.valueOf(i));
when foo() takes an argument of type Object and you pass it a primitive type (int, in this case). It just makes the code easier to type and read.
And that's what happens here. The String.format() method expects objects as argument. You're passing it a primitive type, so the compiler autoboxes it to an Integer for you.

Why int primitive type not deprectaed in Java

In java if Integer can be used instead of int and Integer providing extra features then my question is why is int not being deprecated, and why int primitive type so extensively used?
One simple reason why it is not deprecated is that int is faster. And although you can use both but Integer is a better option(some may disagree as Integer introduces an extra overhead of boxing and unboxing), as it can handle null. int null will become 0.
From the docs:
However, very different things are going on under the covers here. An
int is a number; an > Integer is a pointer that can reference an
object that contains a number.
...
An int is not an object and cannot passed to any method that requires
objects. A common case is in using the provided collection classes (
List , Map , Set ) - though it is possible to write versions of these
classes that provide similar capabilities to the object versions. The
wrapper classes ( Integer , Double , etc) are frequently required
whenever introspection is used (such as in the reflection API).
EDIT:- The Joshua Bloch's reason is also good:
// Hideously slow program! Can you spot the object creation? public static void main(String[] args) {
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum); }
This program gets the right answer, but it is much slower than it should be, due to a one-character
typographical error. The variable sum is declared as a Long instead of
a long, which means that the program constructs about 2^31 unnecessary
Long instances (roughly one for each time the long i is added to the
Long sum). Changing the declaration of sum from Long to long reduces
the runtime from 43 seconds to 6.8 seconds on my machine.
Also check this int versus Integer
Boxed types have poorer performance and require more memory, Primitives are faster. And to avoid creating unnecessary objects.
Integer is an immutable type, once you created, you can't change it, taking much memory and high overhear compare to int
An int is a number; an Integer is a pointer that can reference an
object that contains a number.
int is a primitive type. If not set, the default value assigned is 0. Integer is an object which may contain an int. If the Integer object is not set, the default value is null
If you can use int do so. If the value can be null or is used as an Object e.g. Generics, use Integer
An int is a set construct. For example, only one "int 10" exists and is immutable. Integers on the other hand are full classes that contain an int field among others, have many more methods and are mutible.
int for speed and Integer for versatility.
if you have an method with int as argument, you do not have to nullcheck because it is a primitve type.

Declaration of wrapper classes [duplicate]

This question already has answers here:
How does auto boxing/unboxing work in Java?
(4 answers)
Closed 7 months ago.
This question is in continuation to a question How can a string be initialized using " "?
I would like to raise your attentation that even Integer, Double, Character, Float, Boolean wrapper class can also be declared in the same way String is declared like:
String s = "Test string"
Integer i = 10; //valid
Double d = 10.00; //valid
Boolean b = true; //valid
Does these class are also given special treatment like the String class.
As I pointed out In my previous answer(How can a string be initialized using " "?)
Yes, to retain primitive types in an OOP, designers made bridge between primitives and Object's with Wrappers and they have a special treatment.
The reason is clearly explained in docs.
There are, however, reasons to use objects in place of primitives, and the Java platform provides wrapper classes for each of the primitive data types. These classes "wrap" the primitive in an object. Often, the wrapping is done by the compiler—if you use a primitive where an object is expected, the compiler boxes the primitive in its wrapper class for you. Similarly, if you use a number object when a primitive is expected, the compiler unboxes the object for you. For more information, see Autoboxing and Unboxing
We use primitives extensively in our programs, So it might be a design decision to allowing syntax like
Integer i = 10; //primitive style
Then memory allocates at compile time itself for i since it is a primitive type, when they found with Wrapper type declarations with an Assignment operator =
Syntax wise ,that is more handy and happy(at least for me :)).
Than writing,
Integer i = new Integer(10); //Object creation style
All these following statements:
Integer i = 10; //valid
Double d = 10.00; //valid
Boolean b = true; //valid
are valid because of autoboxing
Autoboxing is the automatic conversion that the Java compiler makes
between the primitive types and their corresponding object wrapper
classes
Yes primitive Wrapper classes also behave like String class.
You can illustrate like below
Integer i1 = new Integer(10); //valid
Integer i2 =10;
System.out.println(i1==i2); // this one is false
i1=10;
System.out.println(i1==i2); //// this one is true
All wrapper classes of primitive types behave this way. It is called autoboxing and was introduced in java 1.5:
http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
String str = "Test String";
having a special treatment is irrespective to and the Integer i = 10;
what is the special treatment String s = "Test String";?
these are called String literals gets the memory in String constant pool of jvm.
the one special significance is in terms of Garbage Collection is, the pooled constants are
never be influenced by garbage collection.
Making 'str' as null does not make "Test String" is eligible for garbage collection.
WHY?:: JVM will try to reuse this "Test String" in future. The garbage collection algorithm excludes the objects which are in pooled memory. so normal GC rules won't apply here. check this out: why String literals are not garbage collected
Now how this treatment is quite different to wrapper's auto boxing. automatic boxing is introduced from JDK1.5. auto boxing & auto unboxing
When Integer i = 10; the compiler replaces this statement with Integer i = Integer.valueOf(10);
only the internal cache wrapper objects of JVM are acts like String literals remaining are not. now what are internal cache wrapper objects?
Integer i = 100;
Integer j = 100;
references i & j are given with a single pre existed object's address.
that is why if( i==j) //true
Integer k = 130;
if( i==k) // false
because k's value is beyond the cache range which is -128 to 127 for Integer.
check this:Integer wrapper behaviour when value range is -128 to 127
In the above if we nullify the reference k then its object undergoes for the GC which is not same treatment like String literals.
If we nullify the i or j then corresponding cached object never be
influenced by GC which is same treatment like String literals.

Why aren't Integers cached in Java?

I know there are similar posts on the topic, but they don't quite address my question. When you do:
Integer a = 10;
Integer b = 10;
System.out.println("a == b: " + (a == b));
This will (apparently) print true most of the time because integers in the range [-128, 127] are somehow cached. But:
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println("a == b: " + (a == b));
Will return false. I understand that I am asking for new instances of an Integer, but since boxed primitives are immutable in Java, and the machinery is already there to do the "right thing" (as seen in the first case), why does this happen?
Wouldn't it make more sense if all instances of an Integer with a 10 be the same object in memory? In other words, why don't we have "Integer interning" which would be similar to "String interning"?
Better yet, wouldn't it make more sense if instances of a boxed primitive representing the same thing, regardless of value (and type), be the same object ? Or at least respond correctly to ==?
It should be very clear that caching has an unacceptable performance hit -- an extra if statement and memory lookup every time you create an Integer. That alone overshadows any other reason and the rest of the agonizing on this thread.
As far as responding "correctly" to ==, the OP is mistaken in his assumption of correctness. Integers DO respond correctly to == by the general Java community's expectation of correctness and of course by the specification's definition of correctness. That is, if two references point to the same object, they are ==. If two references point to different objects, they are not == even if they have the same contents. Thus, it should be no surprise that new Integer(5) == new Integer(5) evaluates to false.
The more interesting question is why new Object(); should be required to create a unique instance every time? i. e. why is new Object(); not allowed to cache? The answer is the wait(...) and notify(...) calls. Caching new Object()s would incorrectly cause threads to synchronize with each other when they shouldn't.
If it were not for that, then Java implementations could totally cache new Object()s with a singleton.
And that should explain why new Integer(5) done 7 times must be required to create 7 unique Integer objects each containing the value 5 (because Integer extends Object).
Secondary, Less Important Stuff: One problem in this otherwise nice scheme results from the autoboxing and autounboxing feature. Without the feature you could not do comparisons such as new Integer(5) == 5. To enable these, Java unboxes the object (and does not box the primitive). Therefore new Integer(5) == 5 is converted to: new Integer(5).intValue() == 5 (and not new Integer(5) == new Integer(5).
One last thing to understand is that autoboxing of n is not done by new Integer(n). It is done internally by a call to Integer.valueOf(n).
If you think you understand and want to test yourself, predict the output of the following program:
public class Foo {
public static void main (String[] args) {
System.out.println(Integer.valueOf(5000) == Integer.valueOf(5000));
System.out.println(Integer.valueOf(5000) == new Integer(5000));
System.out.println(Integer.valueOf(5000) == 5000);
System.out.println(new Integer(5000) == Integer.valueOf(5000));
System.out.println(new Integer(5000) == new Integer(5000));
System.out.println(new Integer(5000) == 5000);
System.out.println(5000 == Integer.valueOf(5000));
System.out.println(5000 == new Integer(5000));
System.out.println(5000 == 5000);
System.out.println("=====");
System.out.println(Integer.valueOf(5) == Integer.valueOf(5));
System.out.println(Integer.valueOf(5) == new Integer(5));
System.out.println(Integer.valueOf(5) == 5);
System.out.println(new Integer(5) == Integer.valueOf(5));
System.out.println(new Integer(5) == new Integer(5));
System.out.println(new Integer(5) == 5);
System.out.println(5 == Integer.valueOf(5));
System.out.println(5 == new Integer(5));
System.out.println(5 == 5);
System.out.println("=====");
test(5000, 5000);
test(5, 5);
}
public static void test (Integer a, Integer b) {
System.out.println(a == b);
}
}
For extra credit, also predict the output if all the == are changed to .equals(...)
Update: Thanks to comment from user #sactiw : "default range of cache is -128 to 127 and java 1.6 onward you can reset the upper value >=127 by passing -XX:AutoBoxCacheMax= from command line"
This would potentially break code written before this design change, when everybody righfully assumed that two newly created instances were different instances. It could be done for autoboxing, because autoboxing didn't exist before, but changing the meaning of new is too dangerous, and probably doesn't bring much gain. The cost of short-lived objects is not big in Java, and could even be lower than the cost of maintaining a cache of long-lived objects.
If you check the source you see:
/**
* Returns an Integer instance representing the specified int value. 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.
*
* #Parameters: i an int value.
* #Returns: an Integer instance representing i.
* #Since: 1.5
*/
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
Source: link
It's the performance reasons why == returns boolean true with integers - it is totally a hack. If you want to compare values, then for that you have compareto or equals method.
In other languages, for example you can use == to compare strings as well, it is basically the same reason and it is called as one of the biggest mishaps of java language.
int is a primitive type, predefined by the language and named by a reserved keyword. As a primitive it does not contain class or any class associated information. Integer is an immutable primitive class, that is loaded through a package-private, native mechanism and casted to be Class - this provides auto boxing and was introduced in JDK1.5. Prior JDK1.5 int and Integer where 2 very different things.
In Java, every time you call the new operator, you allocate new memory and you create a new object. That's standard language behavior, and to my knowledge there is no way to bypass this behavior. Even standard classes have to abide by this rule.
It is my understanding that new will create a new object, no matter what. The order of operations here is that you first call new, which instantiates a new object, then the constructor gets called. There is no place for the JVM to intervene and turn the new into a "grab a cached Integer object based on the value passed into the constructor".
Btw, have you considered Integer.valueOf? That works.
Wouldn't it make more sense if all instances of an Integer with a 10 be the same object in memory? In other words, why don't we have "Integer interning" which is similar to "String interning"?
Because it would be awful!
First, this code would throw an OutOfMemoryError:
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
System.out.printf("%d\n", i);
}
Most Integer objects are probably short-lived.
Second, how would you maintain such a set of canonical Integer objects? With some kind of table or map. And how would you arbitrate access to that map? With some kind of locking. So suddenly autoboxing would become a performance-killing synchronization nightmare for threaded code.
Your first example is a byproduct of the spec requiring that flyweights be created in a certain range around 0. It should never, ever, be relied on.
As for why Integer doesn't work like String ? I would imagine avoiding overhead to an already slow process. The reason you use primitives where you can is because they are significantly faster and take up way less memory.
Changing it now could break existing code because you're changing the functionality of the == operator.
BTW, If you do
Integer a = 234345;
Integer b = 234345;
if (a == b) {}
it is possible that this will be true.
This is because since you didn't use new Integer(), the JVM (not the class code) is allowed to cache its own copies of Integers if it sees fit. Now you shouldn't write code based on this, but when you say new Integer(234345) you are guaranteed by the spec that you will definitely have different objects.
new means new.
new Object() isn't frivolous.
A new instance is a new instance, so they are equal in value, but they are not equal as objects.
So a == b can't return true.
If they were 1 object, as you ask for: a+=2; would add 2 to all int = 10 - that would be awful.
Let me just expand slightly on ChrisJ's and EboMike's answers by giving links to the relevant sections of the JLS.
new is a keyword in Java, allowed in class instance creation expressions (Section 15.9 of the JLS). This is different from C++, where new is an operator and can be overloaded.
The expression always tries to allocate memory, and yields a fresh object each time it is evaluated (Section 15.9.4). So at that point it's already too late for cache lookup.
Assuming your describing the behavior of you code accurately it sounds like autoboxing isn't working on the 'gets' (=) operatior, instead it sounds like Integer x = 10; gives the object x a memory pointer of '10' instead of a vale of 10. Therefore ((a == b) == true)( will evaluate to true because == on objects operates on the memory addresses which you assigned both to 10.
So when should you use autoboxing and unboxing? Use them only when there is an “impedance mismatch” between reference types and primitives, for example, when you have to put numerical values into a collection. It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.
What oracle has to say on the subject.
Notice that the documentation doesn't supply any examples with the '=' operator.
For Integer objects use the a.equals(b) condition to compare.
The compiler will not do the unboxing for you while you compare, unless you assign the value to a basic type.
Please also note that the cache range was -128 to 127 in Java 1.5 but Java 1.6 onward it is the default range i.e. you can set upper value >= 127 by passing -XX:AutoBoxCacheMax=new_limit from command line
It's because you're using the new statement to construct the objetcs.
Integer a = Integer.valueOf(10);
Integer b = Integer.valueOf(10);
System.out.println("a == b: " + (a == b));
That will print out true. Weird, but Java.

Categories

Resources