Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  Pass By Reference Doesn't Work For Wrapper Classes??  (Read 794 times)
0 Members and 2 Guests are viewing this topic.
Offline 2NickPick

JGO n00b
*

Posts: 9



« on: 2011-02-17 05:05:16 »

Here's a curve ball, maybe someone can explain it to me.
Apparently someone decided Wrapper classes won't act like references, but like values?

Program Output:
Quote
intital primitive int: 6
value returned by method call: 100
after method call: 6

inital Wrapper value: 12
value returned by method call: 100
after method call: 12

initial Atomic value: 24
value returned by method call: 100
after method call: 24

correct method primitive: 30
value returned by method call: 100
after method call: 100

Process completed.


Source Code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
public class TestPassByRef
{
   public static void main( String [] args )
   {
      /* not supposed to work. Pass By Value */
      int i = 6;
      System.out.println( "intital primitive int: " + i );
      changeInt( i );
      System.out.println( "after method call: " + i );

      /* Doesn't work. Pass By Ref acts like Pass By Value*/
      Integer wrapperI = new Integer( 12 );
      System.out.println( "\ninital Wrapper value: " + wrapperI );
      changeInteger( wrapperI );
      System.out.println( "after method call: " + wrapperI );

      /* Doesn't work also. */
      AtomicInteger ai = new AtomicInteger( 24 );
      System.out.println( "\ninitial Atomic value: " + ai );
      changeAtomicInteger( ai );
      System.out.println( "after method call: " + ai );

      /* what should be done */
      int i2 = 30;
      System.out.println( "\ncorrect method primitive: " + i2 );
      i2 = changeInt( i2 ); //assign return value of method to original integer
     System.out.println( "after method call: " + i2 );

   }

   private static Integer changeInt( int i )
   {
      i = 100;
      System.out.println( "value returned by method call: " + i );
      return i;
   }

   private static Integer changeInteger( Integer i )
   {
      i = 100;
      System.out.println( "value returned by method call: " + i );
      return i;
   }

   private static AtomicInteger changeAtomicInteger( AtomicInteger i )
   {
      i = new AtomicInteger( 100 );
      System.out.println( "value returned by method call: " + i );
      return i;
   }

}
Offline gouessej

JGO Kernel
*****

Posts: 3560
Medals: 30


TUER


« Reply #1 on: 2011-02-17 05:22:42 »

Hi!

You don't understand how Java works. In this example:
1  
2  
3  
4  
5  
6  
private static AtomicInteger changeAtomicInteger( AtomicInteger i )
    {
        i = new AtomicInteger( 100 );
        System.out.println( "value returned by method call: " + i );
        return i;
    }

The global reference of the object is copied as i is passed as an argument. When you do i = new AtomicInteger( 100 ), you set another local reference, you don't change the global reference which means that the value of i does not change once you get outside your method, it is logical. You should rather use a setter to modify the value contained in AtomicInteger, look at the documentation of this class.

Julien Gouesse
Offline ryanm
« League of Dukes »

JGO Strike Force
*****

Posts: 788
Medals: 4


Used to be bleb


« Reply #2 on: 2011-02-17 05:35:10 »

As gouessej says, java passes everything by value - passing an object passes the value of the object reference.
Games published by our own members! Go get 'em!
Offline gouessej

JGO Kernel
*****

Posts: 3560
Medals: 30


TUER


« Reply #3 on: 2011-02-17 05:45:04 »

As gouessej says, java passes everything by value - passing an object passes the value of the object reference.
That is right, you have better sumed up what I meant. The reference of the object is copied when this kind of argument is used as a method parameter.

Julien Gouesse
Offline 2NickPick

JGO n00b
*

Posts: 9



« Reply #4 on: 2011-02-19 03:40:23 »

So how exactly would I go about changing the global reference rather than creating a new local reference?

I see where the break is...
 
It seemed to me that when I say

changeInteger( wrapperI );

that I'm passing a pointer to an Integer object into the method and inside the method, the parameter i is pointing to the same thing as global variable wrapperI. So when I changed i inside of the method it should also change wrapperI.

BUT, when I said i = new Integer( 100 ), i no longer pointed to what wrapperI pointed to. And I'm assuming ( by looking at the API ) that Integer is immutable, therefore there is no way to change its value without creating a new instance of Integer and assigning to the previous Integer object reference. So it is impossible to change an integer( of any kind) by passing it into a method. You HAVE to assign it in its original scope.

Tell me if I'm wrong.
Offline ryanm
« League of Dukes »

JGO Strike Force
*****

Posts: 788
Medals: 4


Used to be bleb


« Reply #5 on: 2011-02-19 05:05:40 »

Yes, java.lang.Integer is immutable. You would have to define your own mutable integer wrapper class.
Offline Captain Awesome

Full Member
**

Posts: 128
Medals: 3


Hi


« Reply #6 on: 2011-02-19 05:26:35 »

1  
2  
3  
public class IntWrapper {
public int i;
}
Offline gouessej

JGO Kernel
*****

Posts: 3560
Medals: 30


TUER


« Reply #7 on: 2011-02-19 07:57:24 »

So how exactly would I go about changing the global reference rather than creating a new local reference?

I see where the break is...
 
It seemed to me that when I say

changeInteger( wrapperI );

that I'm passing a pointer to an Integer object into the method and inside the method, the parameter i is pointing to the same thing as global variable wrapperI. So when I changed i inside of the method it should also change wrapperI.

BUT, when I said i = new Integer( 100 ), i no longer pointed to what wrapperI pointed to. And I'm assuming ( by looking at the API ) that Integer is immutable, therefore there is no way to change its value without creating a new instance of Integer and assigning to the previous Integer object reference. So it is impossible to change an integer( of any kind) by passing it into a method. You HAVE to assign it in its original scope.

Tell me if I'm wrong.
Rather use your own wrapper with your own write accessor (setInt(int i)).

Autoboxing does not ease these things. When you do i = 100, it is like doing i = new Integer(100); because i is an Integer whereas 100 is an int.

Anyway your way of doing was not right, you should have looked for a modifier in the API to change the enclosed int in the Integer instance. As Integer is immutable, there is no such modifier and you should create your own class.

Julien Gouesse
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.105 seconds with 19 queries.