why identifier of a wrapper class object does not work as a reference variable
Asked Answered
L

4

6

My question involves wrapper classes. I know that when we store a primitive type literal by using wrapper classes, we are storing it as a object of that wrapper class so object's identifier will be a reference variable (somehow like a pointer in c++). For instance, in Integer wi = new Integer("56"), wi is a reference variable. But if that is true:

  1. Why can I do wi++ or wi +=2? Why does compiler deal with those reference variables like normal primitive variables? Doesn't a reference variable store reference of a object?

  2. Given Integer wi = new Integer("56") and int pi = 56, why does (wi == pi) returns true. Isn't wi supposed to store a reference (address)?

And another question: When a reference variable is passed to a method as parameter it counts as passing by reference so the modifiction that happens to that reference variable should affect it's value but it doesn't:

public class Main {
  void show(Integer x){
    x *=100 ;
  }

  void goo(int x){
    x *=100 ;
  }

  public static void main(String[] args) {
    Main mn = new Main() ;
    Integer wi = new Integer("86");
    int pi = 86 ;

    mn.goo(pi);
    System.out.println(pi); //output = 86

    mn.show(wi);
    System.out.println(wi); //output = 86, shouldn't it be 8600?
  }
}
Lanceted answered 23/8, 2013 at 12:49 Comment(4)
1) Autoboxing introudce in java 1.5 2) Cause Integer cache values between -128 to 127, if you do j=new Integer(5) and Integer i =5 i doubt that i==j returns true 3) You shouldn't use new Integer constructor always valueOf or parseXXXMyalgia
It will work fine.Along with several other constructors, it is one of them. Integer o = new Integer("86");Lacteous
@Myalgia That's correct (returns false) when comparing, by reference, two Integer objects. But when comparing int i = 56 and Integer.valueOf(56), the 'reference' equality is true, I imagine because the Integer is unboxed and two int types are compared. @chrylis There is indeed an Integer constructor that accepts a String.Divide
@Lacteous I had somehow managed to overlook that. Still a Bad Thing, though. ;-)Trichromatic
A
4

the statement mn.goo(pi) passes the copy of value 86 while mn.show(wi) passes the copy of reference variable which holds the same object.

  1. why can i do this? wi++ or wi +=2 .i mean why does compiler deal with those reference vriables like normal primitve variables?(doesn't a reference variable store reference of a object?)

Because of the concept of autoboxing and auto-unboxing, wi is converted to primitive, incremented, then then converted back to Wrapper

2.or if we have==>" Integer wi = new Integer("56") " and "int pi = 56" . why does (wi == pi) returns true. isn't wi supposed to store refernce (address)

This is because for Integer wrapper classes, the == will return true for the value till 128. This is by design

For your doubts regarding passign primitives and object references, Please study these programs

class PassPrimitiveToMethod
{
    public static void main(String [] args)
    {
        int a = 5;
        System.out.println("Before Passing value to modify() a = " + a);
        PassPrimitiveToMethod p = new PassPrimitiveToMethod();
        p.modify(a);
        System.out.println("After passing value to modify() a = " + a);
        // the output is still the same because the copy of the value is passed to the method and not the copy of the bits like in refrence variables
        // hence unlike the reference variables the value remains unchanged after coming back to the main method

    }   


    void modify(int b)
    {
        b = b + 1;
        System.out.println("Modified number  b = " + b);
        // here the value passed is the copy of variable a
        // and only the copy is modified here not the variable 
    }       

}

The output is

Before Passing value to modify() a = 5
Modified number  b = 6
After passing value to modify() a = 5

Passing object reference to method

class PassReferenceToMethod
{
    public static void main(String [] args)
    {
        Dimension d = new Dimension(5,10);
        PassReferenceToMethod p = new PassReferenceToMethod();
        System.out.println("Before passing the reference d.height = " + d.height);
        p.modify(d);            // pass the d reference variable
        System.out.println("After passing the reference d.height = " + d.height);
        // the value changes because we are passing the refrence only which points to the single and same object
        // hence the values of the object are modified 
    } 

    void modify(Dimension dim)
    {
        dim.height = dim.height + 1;
    }   


}

The output is

class PassReferenceToMethod
{
    public static void main(String [] args)
    {
        Dimension d = new Dimension(5,10);
        PassReferenceToMethod p = new PassReferenceToMethod();
        System.out.println("Before passing the reference d.height = " + d.height);
        p.modify(d);            // pass the d reference variable
        System.out.println("After passing the reference d.height = " + d.height);
        // the value changes because we are passing the refrence only which points to the single and same object
        // hence the values of the object are modified 
    } 

    void modify(Dimension dim)
    {
        dim.height = dim.height + 1;
    }   


}

The output is

Before passing the reference d.height = 10
After passing the reference d.height = 11
Aegina answered 23/8, 2013 at 12:54 Comment(1)
The Java Language Specification has a whole section discussing exactly how this happens, and it's special treatment for the wrapper types.Trichromatic
R
2

The java compiler automatically inserts intValue and Integer.valueOf calls to convert between int and Integer. For example, here's a code snippet from the question:

void show(Integer x){
  x *=100 ;
}

And here is what really happens:

void show(Integer x) {
  int unboxed = x.intValue();
  unboxed *= 100;
}

As you can see, the line x *= 100 does not really change the Integer object you pass in, it only changes the int value extracted from that Integer object.

In a similar way, the code wi == pi from the question actually means wi.intValue() == pi, which explains your observation.

Ratib answered 23/8, 2013 at 13:35 Comment(0)
Z
0

Java uses the "call by value" concept as described in detail here So in your case x *=100 ; in method show only updates the local variable

Zilber answered 23/8, 2013 at 13:1 Comment(0)
L
0

Compiler unboxes wi to primitive data type.So now, it is a primitive data type,since everything in Java is pass by value, changes in the formal arguments will not affect actual arguements.

mn.show(wi);
Lacteous answered 23/8, 2013 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.