2

Apologies for asking such a primitive question.

I wrote a function which took one parameter; this parameter was supposed to be an in/out parameter.

After debugging, I realized, since there are no explicit reference types in java, I should probably use Integer object (instead of int primitive) as the parameter type. So I changed my function:

boolean getNextFoo(int currentFoo) {
    currentFoo = currentFoo + 1;
}

to:

boolean getNextFoo(Integer currentFoo) {
    currentFoo = currentFoo + 1;
}

After checking the execution in the debugger, I realized this has the same results as the previous. That is, the object that I'm passing into getNextFoo() does not change.

Question 1: How to I achieve in/out parameters with Java (more specifically for primitive types). I thought (pardon me) that objects are always passed by reference.

Question 2: I was checking on the internet for answers and read that Integer is immutable. I understand immutable means constant. If so, why doesn't the compiler (interpreter?) complain when I do currentFoo = currentFoo + 1 within the getNextFoo function?

PS: I see in the debugger that Integer object is actually not being passed to getNextFoo, instead the value of Integer.valueOf is being passed into getNextFoo which is leaving me even more confused.

Code Poet
  • 11,227
  • 19
  • 64
  • 97

6 Answers6

2

Q1: parameters in Java are always passed by value. In the case of objects, you pass the value of the reference, not the reference itself (this is often a cause of confusion). To achieve in/out parameters you have to pass an object that holds a reference to the real parameter.

Q2: immutable means that the object can't be modified, but the variable can. So currentFoo = currentFoo + 1 means: create a new Integer with value currentFoo + 1, then assign this new object to currentFoo.

Viruzzo
  • 3,025
  • 13
  • 13
  • I guessed it's creating a new Integer instance with the value of `(currentFoo + 1)`. But `Integer` is also an object. If I cannot do `myObject = myOldObject` to create a copy of `myOldObject` how is the compiler creating a copy of Integer which is also an object? If my intension is to create a copy, I have to define a copy constructor in myOldObject class in order to be able to copy it. Even then, I have to explicitly call `myObject=new MyObject(myOldObject)` to get a copy. – Code Poet Dec 02 '11 at 11:23
  • `currentFoo = currentFoo + 1` is in fact basically equivalent to `currentFoo = new Integer(currentFoo + 1)` – Viruzzo Dec 02 '11 at 11:30
1

Answer 1:

One approach would be to pass in an AtomicInteger, which is mutable.

boolean getNextFoo(AtomicInteger foo) {
  foo.set(foo.get() + 1);
  return true;
}

Answer 2:

The statement: currentFoo = currentFoo + 1 is not modifying the object; it is creating a new Integer instance and reassigning the local reference to point to it.

When you exit from the method the local reference is "lost" (i.e. it goes out of scope) and hence reassigning it has no effect outside of the method.

Adamski
  • 54,009
  • 15
  • 113
  • 152
  • I guessed it's creating a new Integer instance with the value of `(currentFoo + 1)`. But `Integer` is also an object. If I cannot do `myObject = myOldObject` to create a copy of `myOldObject` how is the compiler creating a copy of Integer which is also an object? If my intension is to create a copy, I have to define a copy constructor in myOldObject class in order to be able to copy it. Even then, I have to explicitly call `myObject=new MyObject(myOldObject)` to get a copy. – Code Poet Dec 02 '11 at 11:17
0

Integer is immutable, that's why its value cant be changed.

why doesn't the compiler (interpreter?) complain when I do currentFoo = currentFoo + 1

because when u do currentFoo = currentFoo + 1 a new Integer is created on heap and its reference is assigned to the currentFoo.

For Integer, if you want to get changed value outside the function, either you can return the value from the function, OR you can put the integer into array/ArrayList and pass that array/ArrayList to the function. Now get change the value, it will be reflected outside the function.

Zohaib
  • 7,026
  • 3
  • 26
  • 35
0

Question 1: How to I achieve in/out parameters with Java (more specifically for primitive types). I thought (pardon me) that objects are always passed by reference.

Pass the mutable class object which has member variable of type int and update the member variable thru the object.

Question 2: I was checking on the internet for answers and read that Integer is immutable. I understand immutable means constant. If so, why doesn't the compiler (interpreter?) complain when I do currentFoo = currentFoo + 1 within the getNextFoo function?

new object will be created and will be assigned to currentFoo.

Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94
0

Question 2. Calling currentFoo = currentFoo + 1 when working with results in a new object being created and its reference stored in currentFoo. The compiler doesn't complain because it's not invalid Java - it just results in a new object being created, rather than the current one being updated.

Anthony Grist
  • 38,173
  • 8
  • 62
  • 76
0

Question 1:

You could pass an array of 1 int, and change the unique element value, or pass a mutable integer wrapper object (like AtomicInteger, for example). Or, instead of using in/out parameters, your method could return an object containing a boolean field and an integer field.

Question 2:

currentFoo = currentFoo + 1

is the same as:

int tmp = currentFoo.intValue(); // auto-unboxing
tmp = tmp + 1;
currentFoo = Integer.valueOf(tmp); // auto-boxing

A new Integer instance is thus assigned to currentFoo. The original instance (being immutable) is not modified.

All parameters are passed by value in Java. When using objects, the reference to the object is passed, and it's passed by value: a copy of the reference is made and passed to the method. If you assign something to the passed reference, you assign it to a copy, and the original reference is thus still pointing to the original object.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255