Reassigning an Object parameter
Tags: java, niche, mutability, parametervsargument
Published: 2020-11-27 12:40:24



Welcome back to my series, where I go over the little java quirks and obstacles that I encountered on my journey. In this installment I will discuss one of the concepts that I struggled to wrap my head around and that is: reassigning an parameter variables. I am referring specifically to reassigning **object parameters** because the concept of mutability only applies to non-primitive data types.

I'll begin by describing what I was trying to do and later on I will explain why it did not work.

# The Problem :anger:

There came a time where I decided it was a good idea to reassign an object inside of a method. I was trying to be clever and Java just did not want to play along. The method went something along the lines of...

```java

public static void process(Contact[] arr) {

	Contact[] result;
	boolean condition;

	//traverse the array 
	int i = 0;
	for (String element: arr) {

		condition = someCriteria(element);

		if (condition) {

			result[i] = element; 
			i++;

		} // if

	} // loop

	arr = result;
 
} // remove method

public static void main(String[] args) {
	

	Contact[] mydata = readInContacts();
	process(mydata);
}

```   
At first glance, you may get the impression that this code is flawless, after all it was written by myself :smirk:. The program reads in text from a CSV file and creates contact objects from it. I then took that list of contact objects and made an array out of them. My aim was to create an impure method, `process()` , that filters out objects in an array that met some criteria. The intention was to create a new array of a different size and assign that new array to the parameter, thinking that it would make those changes to the original argument. When the code was run, it left the argument unchanged.

You can try and find out what is wrong with it but I think its pointless unless you really have a thorough understanding of Java. The error is on the 3rd line of code from the bottom (`arr = result`). Let me explain, when you reassign a parameter variable, it **does not** make any changes to the argument variable. Java will not throw an error or tell you that what you are doing is illegal. You will just have to suffer there in silence, questioning logic and your ability to code altogether.

So just to be clear...

```java

public static void modify(int[] args) {

	data args = new int[]

}

public static void main(String[] args) {

	int[] myarr = new int[] {1,2,3,4,5,6};


	modify(myarr);
	System.out.println(Arrays.toString(myarr)); // [1,2,3,4,5,6,7]

	myarr = new int[] {1,2,3}
	System.out.println(Arrays.toString(myarr)); // [1,2,3]
}

```

The `modify` method will not make any changes to the `myarr` array because you cannot reassign an argument inside of a method.

Note: :clipboard: You may want to familiarise yourself with the concept of mutability before continuing. Knowing the difference between pure and impure methods should suffice. 

## Parameter vs Argument

I often hear the words argument and parameter used interchangeably even though they are not the same thing. To avoid confusion I'll define an argument, a parameter, and help you distinguish between them. 

An **argument** is a variable, which usually holds a value of the variables data type, that you pass into a method. A **parameter** is an alias or copy of the argument, and if it is of a reference data type then we can use it to manipulate the argument inside the scope of a method that it was passed into.

![Argument vs Parameter](https://dev-to-uploads.s3.amazonaws.com/i/2thtxuo2xuye5lhny2hs.PNG)

If we call this `greet` method and pass in the argument `name` , like so `greet(name)`, then we say `name` is the argument that was passed into the `greet` method. `aName` is what we call the parameter. Whenever greet is called with an argument, `aName` will take on the value of that argument. The argument and the parameter are separate entities. The parameter is a temporary alias of the argument that only exists inside the scope of the method that uses it.

**Hint:** :bulb: It is good practice to name parameter variables with an "a" prefix to the name of the argument. It helps, whoever is reading the code, keep track of which variables are arguments and which ones are parameters as well as which arguments are assigned to which parameters.

Parameters, like variables, can be a primitive or a reference data type. Java handles them differently in each case. 

#### When parameters are primitive

When parameters are of a primitive data type then Java will simply create a separate copy the value the argument in memory. 

![primitive parameters and arguments](https://dev-to-uploads.s3.amazonaws.com/i/co8iut6kxvpxk880zupt.PNG)

The parameters and arguments are separate entities in this case. If the paramater, `aName`, is changed in any way, it will not affect the argument. When the value in address A changes, it has no effect on the value in address B. 

#### When parameters are non-primitive(reference data type)

When dealing with reference data types, variables do not store the object assigned to it, but it stores a pointer which has the address of where the object is stored in memory. 

When parameters are of a reference data type then Java will **not** create a separate copy of the object in memory but it will create a separate copy of the **pointer** argument. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/q39wllfr6umlaair0s0n.PNG)

It is because we are dealing with pointers that we have the power of mutability. If 2 pointers point to the same address (object) in memory and either one makes changes to it, then the other will reflect those changes. This means that by changing the attributes of objects that are referenced by parameter then the object referenced by the argument variable will reflect those changes. This is because both the parameter and argument will point to the same object the same object in memory. 

In other words, if the parameter variable, `arr` makes changes to the array that it references in address A then the argument `myarr` will also have those changes because they reference the same object 

However... If you decide to change the address that the parameter points to, by assigning a parameter to a new object all together, then the parameter and the argument will no longer point to the same object meaning that they will become separate entities, and any changes made to one will not affect the other. To be clear, if you **reassign an object parameter** you are changing the address that parameter points to.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/h5x5lw2zrtam0qt37cbe.PNG)

If we assign the parameter, `arr` to a new array, which is stored in Address B, we will no longer be able to mutate or make changes to the argument by changing the parameter.

# The Solution :bulb:

There are many ways to work around this issue that I had, it all depends on the situation. I had to resort to changing the `filter()` method by returning the filtered array and use the `object = object.method()` syntax to store the result parameter and store that in the argument. I know it is not the most elegant solution but I was pressed for time. I should have actually used a LinkedList because by doing so, I would have been able add and remove objects from my List by using the `.add()` and `.remove()` methods on the parameter and it would mutate the argument, meaning there would be no need for the reassignment of the parameter. Alternatively, I could have declared a global variable that I would manipulate inside any method, removing the need for a parameter and argument to reference the object of interest.

# Summary

Any changes made to a parameter variable within a method mutates the original argument, provided that they are of a reference data type. This happens because both the argument and parameter point to the same object in memory. When you reassign a parameter variable, you are changing the object that it references in memory and so it will not make any changes to the argument.

The concept of mutability is powerful, that is if you know how it works and when to use it. Mutability allows us to make code that is more intuitive and self explanatory. `sort(list)` is much easier for beginners to interpret than `list = sort(list)`. This problem I had is just one of those corner cases that I thought could have done with better explaining. It would have saved me a lot of time. 

As always thanks for the read and Happy Coding :computer:!