I am relatively new to Java and while trying out some code came across something that surprised me. Hopefully some one can shed some light on this. Here’s some code snippets relevant to my question. Those who’ve read the practice of programming might find this familiar.
This function is defined for the List datatype, and applies the passed “fn” argument (which is nothing but a function wrapped in an object) to all members of the list.
public void apply(MapFunctionI fn, Object fnArg) {
Node curr = head;
for (; curr != null; curr = curr.getNext()){
fn.function(curr.getItem(), fnArg);
}
}
Next, I try to use this function to count the number of elements in a list using a class that implements MapFunctionI (an interface that requires a method called ‘function’)
class CounterFunction implements MapFunctionI {
public void function(Object node, Object arg){
((MyInteger)arg).increment();
}
}
Here’s how I call this.
static void TestApply(LinkedList l){
System.out.println("Number of elements in List -> ");
MyInteger n = new MyInteger(0);
l.apply(new CounterFunction(),n);
System.out.println(n.value());
}
And here’s the MyInteger type.
class MyInteger {
private int n;
MyInteger(int i){
n = i;
}
public void increment(){
n++;
}
public int value(){
return n;
}
Now, if you’re wondering why I am using my own Integer type, that’s what my question is related to. I tried using the Java Integer type for this, but I could not get it to work, the answer printed was always O, the value of the “Integer” did not persist across multiple invocations. Here’s how I was doing it,
arg = ((Integer)arg).intValue() + 1;
What explains this behavior?
And I am sure there is a more succinct way of posing this question 🙂
The first problem is that type
Integeris immutable; once created with a certain integer value, that value cannot be changed. So you can’t directly change an Integer (I’m not saying you didn’t know this or tried to).The next problem is that what gets passed to the function is a reference to that Integer. You can, inside the function, change that reference to point to a different-valued Integer, but the changed reference from inside the function is never passed back out to the calling function, so its value isn’t relevant there.
The reason why your home-built class works is that you are now changing the internal contents of your object and not just a reference to it. The very same object exists inside and outside your function, so when you change it inside, the change is indeed seen outside.