Newaz Sharif Amit
Newaz Sharif Amit

Reputation: 197

What's the reason for different output here?

int a = 2;
int b = a + a;

Class cache = Integer.class.getDeclaredClasses()[0]; 
Field myCache = cache.getDeclaredField("cache"); 
myCache.setAccessible(true);

Integer[] newCache = (Integer[]) myCache.get(cache); 
newCache[132] =  newCache[133];

System.out.printf("%d",b); // 5
System.out.println(b); // 4

Here I change the value of cache[132] to cache[133] that means now cache[132] == 5 in printf() method it prints 5 fine but in println() why it prints 4 it should be 5 what's the reason behind on it?

Upvotes: 10

Views: 363

Answers (3)

nits.kk
nits.kk

Reputation: 5316

If you try below code

System.out.println(Integer.valueOf(b)); 

You will notice 5 being printed for this. Now for the printf method you have below code.

System.out.printf("%d",b); 

If you see printf accepts String as first parameter and Object as second parameter. You have b as primitive type (int). Auto boxing takes place and for it Integer.java class method : valueOf(int i) is used.

Also if you declare Integer then you will see 4 being printed in both the cases as no auto boxing happens. usually -128 to 127 are cached and you have modified the internal cache. valueOf uses the cache and that is the reason you see different oputputs

Upvotes: 1

Ivan Valeriani
Ivan Valeriani

Reputation: 630

After javap -verbose package.YourClassName

    51: getstatic     #67                 // Field java/lang/System.out:Ljava/io/PrintStream;
    54: ldc           #73                 // String %d
    56: iconst_1
    57: anewarray     #3                  // class java/lang/Object
    60: dup
    61: iconst_0
    62: iload_2
    63: invokestatic  #75                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    66: aastore
    67: invokevirtual #79                 // Method java/io/PrintStream.printf:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
    70: pop
    71: getstatic     #67                 // Field java/lang/System.out:Ljava/io/PrintStream;
    74: iload_2
    75: invokevirtual #85                 // Method java/io/PrintStream.println:(I)V
    78: return

You see that at instruction 63 Integer.valueOf gets called, thus using the Integer cache. At point 75 println signature doesn't take an object but rather a straight primitive int, so no Integer cache involved.

Upvotes: 1

Paul Boddington
Paul Boddington

Reputation: 37645

println has an overload which accepts an int. Therefore in the line

System.out.println(b);

the int is never converted to an Object using Integer.valueOf.

printf has signature

public PrintStream printf(String format, Object ... args)

so 4 is autoboxed to the Integer object 5 (using the modified cache), and so 5 is printed.

Upvotes: 6

Related Questions