Tagged: reference

By reference or by value?

Since this is my first post, i will start really small and build from there in the future.

I’d like to show some code about how java passes arguments between functions. In the first example we will use primitive types (int, float, etc), while in the second we will use instances of some class.

First example:

public void testModifiedString() {
String originalString = "first string";
int originalNumber = 10;
StringModifier test = new StringModifier(originalString, originalNumber);
String beforeMethodOne = test.string + " " + test.number;
System.out.println(beforeMethodOne);
StringModifier.methodOne(test.string, test.number);
String afterMethodOne = test.string + " " + test.number;
System.out.println(afterMethodOne);
assertEquals(afterMethodOne, beforeMethodOne);
}

Where StringModifier has two public fields, string and number, and methodOne(String s, int number) is:

public static void methodOne(String s, int number) {
s = "string modified by methodOne";
number = 0;
}

Everyone can guess the output of this test, right? It will print out

first string 10
first string 10

suggesting us that, in Java, the primitive types are passed by value: methodOne will work on copies of its parameters, not affecting the original ones.

Let’s go one step further, and let’s try this with classes. Let’s take a look at the following short test case:

public void testMoveCircle() {
int origin = 0;
Circle myCircle = new Circle(origin, origin);
int delta = 10;
myCircle.printCoordinates();
CircleMover circleMover = new CircleMover();
circleMover.moveCircle(myCircle, delta, delta);
myCircle.printCoordinates();
assertEquals(origin + delta, myCircle.getX());
assertEquals(origin + delta, myCircle.getY());
}

We build a new Circle in the origin (0, 0) and print its coordinates. Then, we build an object CircleMover that will try to move myCircle to a new place (10, 10) and reprint the coordinates.
The output will be:

coordinates: x = 0 y = 0
coordinates: x = 10 y = 10

as we could guess from the test. But if we look inside the moveCircle‘s body, we notice something we didn’t expect:

public void moveCircle(Circle circle, int deltaX, int deltaY) {
circle.setX(circle.getX() + deltaX);
circle.setY(circle.getY() + deltaY);

//code that tries to assign a new reference to circle
circle = new Circle(0, 0);
circle = null;
}

This means that the method changes the circle’s coordinates, but also tries to modify the reference to the object passed, building a new Circle. Seeing that we can’t overwrite the reference circle, we guess that it is just a pointer passed by value to the function.

I published a gist on github if you want to let you see and download the files and/or add tests. Contact me if you find errors or want to share some ideas.

Advertisements