Email address:
Password:
SCJP/OCPJP 1.6 certification
Practice Exams and Training
SCJP Online Training » Discussions

Question 52 prac 3

In this question Integer object "IN" is passed in method argument "mn". Then IN and mn variables should refer to same object and incremented value should be printed.

If This rule is not applied for wrappers.

Wrappers are immutable - you can't change the values a wrapper object contains once it has been initialized. However, with the support of boxing and unboxing, you can see an 'illusion' to a mutability. For example, consider this code:


Integer a = 2;
a = a + 1;       // which is same as to a++;
System.out.println(a);


The above code prints 3, but that's not because the value of the Integer object a contained has changed. Instead, the + operator creates a NEW Integer object, and when you are printing it at the third line, you are printing that new object. Ignoring the possible pooling, the object we created at line-1 will become eligible to the garbage collector after the execution of line-2. In other words, the above code is equivalent to this:


Integer a = new Integer(2);

int temp = a.intValue(); // auto-unboxing
temp = temp + 1;
a = new Integer(temp); // auto-boxing

System.out.println(a);


See? It's a new object.


Following the same flow, when you do this to a method parameter, you are only assigning a new object to the method parameter. For example, following two code fragments are equivalent:


  public static void increase(Integer mn){
    mn++;
  }

  public static void increase(Integer mn){
    int temp = mn.intValue();
    temp++;
    mn = new Integer(temp);
  }


As you can see, it only assigns a new object to the parameter, without changing what the parameter has originally contained.

So Apart from Wrappers and String . All the Other classes will follow that rule i.e the variable passed in argument and variable in caller method will refer to same object and any changes in object will reflect to both variables


public static void increase(Myclass mn){
    mn.i=10;
}
class Myclass{
  int i=2;
  public static void main(String... mn){
    Myclass m=new Myclass();
    increase(m);
    SOP(m.i);             // should print 10   (am i write?)            
  }
}

No, there is no difference between wrapper classes and other classes in this case.


Your statement "argument and variable in caller method will refer to same object and any changes in object will reflect to both variables" is correct, but it does not apply to our example on wrapper classes, because there is NO method like setValue() defined in any of the wrapper class. There is no method in any of the wrapper classes that can change the primitive value contained within it.


In your example above, of course should print 10, because you are changing the primitive value within the Myclass object by directly altering the primitive variable as in mn.i=10. Again, in wrapper classes, the primitive value it wraps is a private variable, and therefore you can't change it. Same way, if we make the variable i private in your program, this is what it would look like:


public static void increase(Myclass mn){
    // Assuming we're on a different class, you can't access mn.i now because it's private.
    // So we do this, which is what it happens behind the scene with auto-boxing and auto-unboxing.
    int i = mn.getI();
    i += 10;
    mn = new Myclass(i);
}

.......

class Myclass{

  private int i=2;

  public Myclass(int i) {
    this.i = i;
  }

  public int getI() {
    return i;
  }

  public static void main(String... mn){
    Myclass m=new Myclass();
    increase(m);
    SOP(m.i);             // this still prints 2          
  }
}


Does that sound a bit more clearer?

ExamLab © 2008 - 2024