Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Reflection Snippet output

I was just exploring java reflection API and i encountered following code snippet

public class Main {
    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException{
            Field value=Integer.class.getDeclaredField("value");
            value.setAccessible(true);
            value.set(42, 43);

            System.out.printf("six times seven %d%n",6*7);
            System.out.printf("six times seven %d%n",42);
            System.out.println(42);
        }
    }

Output :

six times seven 43
six times seven 43
42

I read the documentation of the set method which states that it sets value of the field for the given object. But i am not able to understand the output of the code because it should print 42 in all the cases.

Can anyone please give insight into what is happening in the code ?

like image 362
Ankur Trapasiya Avatar asked May 09 '13 16:05

Ankur Trapasiya


1 Answers

        System.out.println(42);

is calling println(int) not println(Object). The boxing never happens. That makes it faster, and also worked prior to 1.5.

In the other cases, you are boxing through Integer.valueOf(int). This method is defined as always returning exactly the same Integer objects for values between -128 and 127 inclusive (may or may not have the same behaviour for other values). So wherever 42 is boxed in your program you will get the same object, and when you set the value of value in this object it changes no matter which reference it is read through.

If you were to put in the boxing explicitly into the code, it would look like this:

        value.set(Integer.valueOf(42), 43);

        System.out.printf("six times seven %d%n",Integer.valueOf(6*7));
        System.out.printf("six times seven %d%n",Integer.valueOf(42));
        System.out.println(42);

As we know Integer.valueOf( returns exactly the same object for 42, the code is effectively:

        Integer obj42 = Integer.valueOf(42);

        value.set(Integer.valueOf(obj42, 43);

        System.out.printf("six times seven %d%n", obj42);
        System.out.printf("six times seven %d%n", obj42);
        System.out.println(42);
like image 68
Tom Hawtin - tackline Avatar answered Oct 01 '22 12:10

Tom Hawtin - tackline