Reputation: 197
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
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
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
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