4

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.

Community
  • 1
  • 1
Sourabh Bhat
  • 1,793
  • 16
  • 21

3 Answers3

5

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));
mkobit
  • 43,979
  • 12
  • 156
  • 150
4

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).

Dici
  • 25,226
  • 7
  • 41
  • 82
  • Thanks for the answer and thanks for clearing my doubt regarding the arrays. What I conclude from your and other answers is that autoboxing is done locally when required, and therefore int[] will need less space than Integer[]. Can you please elaborate on the last statement. Do you mean that references are not used if the value wrapped in Integer is between -128 and 127? – Sourabh Bhat Oct 04 '14 at 09:39
  • When you instantiate an Integer between -128 and 127, the JVM first look up in an Integer pool if the value already exists in the pool. If it does, the reference of the existing Integer wrapping this value is returned, otherwise a new Integer is created, added to the pool, and returned. It enables to reduce the number of Integer references because most of the time we use low values of integers rather than high values. – Dici Oct 04 '14 at 12:09
  • You can read the some of the 3 first answers of this question to have it explained in a better way : http://stackoverflow.com/questions/13098143/java-integer-constant-pool – Dici Oct 04 '14 at 12:14
  • Thank you so much. This helped me remove another bug from my code, which I was not able to comprehend. As my code was working for smaller data sets but not for larger ones. Now I understand why! – Sourabh Bhat Oct 04 '14 at 18:07
3

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255