Arrays in Methods: pass by value and pass by reference


We saw in our Java course that there is a section just for methods, and we are in another section of the course just to arrays.
There are two important things, and the interaction between them is also important.
However, there are some details that need to be clarified and commented that we'll see in this article.



Passing arrays/vectors for methods

To call the methods using arrays as arguments, there is no secret.
Do as always:

methodName (variableName);

Do not worry about the type and the brackets, [], because the methods are already prepared and know what you are sending is an array and not a common type.

To declare, however, that there is a difference:
public static returnType methodName (parameterType[] variableName);

For example, let's use the example code from the last article of our course to create a method called 'showMatrix' that displays a matrix.
This method displays a 3x3 matrix of integers and be implemented by:

public static void showMatrix (int [] [] mat) {
/ / code
}

Note that our matrix has two dimensions, so we used two pairs of brackets.

Putting the code that displays among this method and making the call in the main, our example looks like this:

Java Code: Fills and displays a 3x3 Matrix


import java.util.Scanner;

public class arrayToMethod {
    
    public static void showMatrix(int[][] Mat){

        System.out.println("\nThe Matrix is now: \n");
        for(int line=0 ; line < 3 ; line++){
            for(int column = 0; column < 3 ; column++){
                System.out.printf("\t %d \t",Mat[line][v]);
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args){
            int[][] matrix = new int[3][3];
            
            Scanner entrada = new Scanner(System.in);
            System.out.println("Matrix M[3][3]\n");
            
            for(int line=0 ; line < 3 ; line++){
                for(int column = 0; column < 3 ; column++){
                    System.out.printf("Input the element M[%d][%d]: ",line+1,column+1);
                    matrix[line][column]=entrada.nextInt();
                }
            }
            
            showMatrix(matrix);
            
           
        }


}

Pass by value and pass by reference

If you've studied other languages ​​such as C or C++, you know what are these kind of parameter passing, its importance as well as its confusion.

Often we want to pass a value to method to this value to be changed. In this case, we are passing by reference, ie, it is as if we are actually passing the variable itself to be modified and receive another value within the method.

When we passed by value, the method take a copy of our variable and work with that copy, and does not alter our variable. Changes and works only with the copy, leaving our original variable intact.

Both types of passing are useful and have their functionality depending on what you want to do.
However, in Java programming language the parameter passing is always, ALWAYS, made ​​by value.
Whenever we create a variable of a type, we pass a copy of its value to the method.

Consider this example, where we define a number of 2112 value, it is doubled inside the method and print again. Its value does not change:

Java Code: passing by value demo, the method does not change the variable value

public class passingByValue {
    
    public static int doubleMethod(int num){
        return num*2;
    }
   
    public static void main(String[] args){
            int number=2112;
           
            System.out.println("Number initial value: " + number);
            System.out.println("Passing the number to double method");
            doubleMethod(number);
            System.out.println("Valeu after mehotd: " + number);
           
        }

}



The variable 'num' is duobled inside the method, but it is just a copy of the 'number'  variable from method 'main'.
The value of 'number' is not touched or seen by method 'doubleMethod()'.


Reference types in Java

There are types in Java that are called 'reference types', which are variables that, by nature, get a reference, ie, they point to another value (more specifically, they do not store the value in memory, they store an address another block of memory - ie, has a reference to other memory address).
As an example, we know that Java objects are, in general, and the current theme of our study, the arrays are 'reference type' too. So, our classes and arrays are reference types.

When we declare an object eg with the name 'myObject' actually this 'myObject' will keep a reference of the real object. That is, in Java, references types do not store the value in memory, but an address - who have already studied C pointer will understand easily!

This is all due to the fact that objects and arrays do not have defined sizes, as primitive types. So it is more 'complicated' to Java treat this kinds of data, because they do not have an exact size.
So instead of dealing with their exact values ​​(value), he treats them by reference (reference).

The confusion lies in the fact that when these types of variables passed to the methods they change in value! But wait, why?
How so? But in Java, the passing is not always by value?

Actually, there are two types of calls: those that use copy of the primitive types and those using copies of the reference object. However, as it is a bit advanced and we did not see objects, we'll give a simplified explanation.

Values ​​of type 'primitive', a copy is generated in the method and all changes are made in that copy, ok?

In the values ​​of type 'reference' ,the same, because Java only passes by value! Ok?
So int the method is created another copy of the object! That is, we have another reference pointing to the same location in memory. Good.

In passing of the type 'reference', the second copy inside the method, changes the reference. But the reference points to a location in memory! So we changed the location in memory when we change the reference!

Now if the two variables point pro same place and one of these place changes the pointed location, this location will be changed to both . That's the trick!


Example of how the passage of type reference works

If I do I declare my original reference type with value 'x' actually this variable points to my memory where the value really is.
When I send to method, the method creates a copy of that reference type variable, but the damned copy also points pro same memory location. So we have two variables pointing to the same memory location, where is the 'x'.

But the method proceeds and changes the value of 'x' through that copy. Actually, the 'x' value in memory was changed. Now this value 'x' is 'x +1', and the method is over now.

Back to where the method was called, my original reference type variable still points to the same memory location. However, that place no longer exists 'x' anymore, not there is 'x +1' and have the false impression that we pass a value by reference. But yes, passed by value, because the method work with the copy!

Here's an example where we create a method that calculates the trace of a 3x3 matrix.
Trace is the sum of diagonal elements of the matrix, that is, elements whose row number is equal to the number of column:


Java code example: Program that calculate the trace of any 3x3 Matrix
import java.util.Scanner;

public class trace{
    
    public static void showMatrix(int[][] Mat){

        System.out.println("\nThe Matrix is: \n");
        for(int line=0 ; line < 3 ; line++){
            for(int column = 0; column < 3 ; column ++){
                System.out.printf("\t %d \t",Mat[line][column]);
            }
            System.out.println();
        }
    }
    
    public static int trace(int[][] Mat){
        int sum=0;
        
        for(int line=0 ; line < Mat.length ; line++){
            sum += Mat[line][line];
        }
        
        return sum;
    }
 
    public static void main(String[] args){
            int[][] matrix = new int[3][3];
         
            Scanner input = new Scanner(System.in);
            System.out.println("Matrix M[3][3]\n");
         
            for(int line=0 ; line < 3 ; line++){
                for(int column = 0; column < 3 ; column ++){
                    System.out.printf("Insert the element M[%d][%d]: ",line+1,column+1);
                    matrix[line][column] = input.nextInt();
                }
            }
         
            showMatrix(matrix);
         
            System.out.println("\nThe matrix trace is: "+ trace(matrix));
        }


}



Example passing reference type in real life

Suppose I wrote down an address on a paper, the address of a building.
In short: I have a reference of this building.

The paper is my reference type variable. That is, it does not have the building. It has an address (reference). Well, easy until now, right?

Now let's do a 'method'. That is, we take a copy of this paper and give to a suicide bomber.
Ok, now the bomber has one paper with the reference (adress) too!
Both papers point to same location: the building.

That is what the method does. Creates a copy of the reference - it explaint why, in Java, the parameter passing is always by value, since it works with the copy.

So now our bomber will work with this copy (as does the method).
He goes there and explode the building.
He moved my paper? No, it remains intact, as predicts the by value passing.

But he changed the place where my paper was referring to.
He changed it based on his paper. But his paper had the same address as mine!
So if him changed to where his paper pointed, this change will happen for me too, because my reference also pointed to the same building (R.I.P) !



In short, if it was confusing, here's a summary of what interests us at this point of the course:
- If you pass primitive types (int, float, double, etc.), they will not be altered by methods
- If you pass arrays, they are changed by methods. As well as all kinds of Classes

To read more about it, Java in a Nutshell: http://docstore.mik.ua/orelly/java-ent/jnut/ch02_10.htm


No comments: