Pass By Reference Doesn't Work For Wrapper Classes??

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.
[/quote]
Source Code:

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;
	}

}

Hi!

You don’t understand how Java works. In this example:

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.

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.

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.

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

public class IntWrapper {
public int i;
}

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.