domingo, 14 de fevereiro de 2016

Passagem de parâmetros - Java


Olá,


No artigo de hoje vamos discutir sobre como funciona a passagem de parâmetros para os métodos em Java.

Primeiro, vamos ao conceito de passagem de parâmetros:

Passagem de parâmetro por valor: O método recebe uma cópia do valor da variável como argumento. Esse valor pode ser utilizado e alterado dentro do método, o que não afetará o valor inicial da variável que foi passada.

Exemplo em C:

#include <stdio.h>
#include <stdlib.h>


void soma (int valor1, int valor2) {
   valor1 = 10;
   valor2 = 20;
   
   printf("\n\nDentro do metodo: ");
   printf("\n valor 1: %d", valor1);
   printf("\n valor 2: %d", valor2);
       
   printf("\n soma = %d", valor1 + valor2);
}

main () {

   int valor1 = 0;
   int valor2 = 0;
   
   printf("\n\nAntes do metodo: ");
   printf("\n valor 1: %d", valor1);
   printf("\n valor 2: %d", valor2);
   
   soma(valor1, valor2);
      
   printf("\n\nDepois do metodo: ");
   printf("\n valor 1: %d", valor1);
   printf("\n valor 2: %d", valor2);

   printf("\n\n");
   system("PAUSE");
   
   return 0;   
}

Saída:

Antes do metodo:
 valor 1: 0
 valor 2: 0

Dentro do metodo:
 valor 1: 10
 valor 2: 20
 soma = 30

Depois do metodo:
 valor 1: 0
 valor 2: 0

Passagem de parâmetro por referência: O método recebe uma referência para a variável como argumento. Quaisquer alterações feitas na variável dentro do método, afetará o valor dessa fora dele.

Exemplo em C:

#include <stdio.h>
#include <stdlib.h>


void soma (int *valor1, int *valor2) {
   *valor1 = 10;
   *valor2 = 20;
   
   printf("\n\nDentro do metodo: ");
   printf("\n valor 1: %d", *valor1);
   printf("\n valor 2: %d", *valor2);
       
   printf("\n soma = %d", *valor1 + *valor2);
}

main () {

   int valor1 = 0;
   int valor2 = 0;
   
   printf("\n\nAntes do metodo: ");
   printf("\n valor 1: %d", valor1);
   printf("\n valor 2: %d", valor2);
   
   soma(&valor1, &valor2);
      
   printf("\n\nDepois do metodo: ");
   printf("\n valor 1: %d", valor1);
   printf("\n valor 2: %d", valor2);

   printf("\n\n");
   system("PAUSE");
   
   return 0;   
}

Saída:

Antes do metodo:
 valor 1: 0
 valor 2: 0

Dentro do metodo:
 valor 1: 10
 valor 2: 20
 soma = 30

Depois do metodo:
 valor 1: 10
 valor 2: 20

Perceba que em C a passagem de parâmetro por referência é feita por meio de ponteiros, de forma que o método recebe como argumento o endereço da memória onde está armazenado o valor da variável, permitindo que as alterações sejam feitas diretamente nela.

Como já sabemos, em Java não existem ponteiros, ou seja, não é possível acessarmos a memória do computador diretamente, isso é feito pela JVM. Portanto, não existe passagem de parâmetro por referência em Java, apenas por valor.

Mas o que acontece ao executarmos o código abaixo em java?

public class TesteObj {
    public static void main(String[] args) {
        Valor valor1 = new Valor();
        int valor2 = 10;
        
        System.out.println("\nAntes do metodo");
        System.out.println("Valor1 (Objeto): "+ valor1.getValor());
        System.out.println("Valor2 (Primitivo): "+ valor2);
        
        soma1(valor1, valor2);

        System.out.println("\nDepois do metodo");
        System.out.println("Valor1 (Objeto): "+ valor1.getValor());
        System.out.println("Valor2 (Primitivo): "+ valor2);
        
    }
    
    public static void soma1(Valor valor1, int valor2) {
        valor1.setValor(10);
        valor2 = 20;
        
        System.out.println("\nDentro do metodo");
        System.out.println("Valor1 (Objeto): " + valor1.getValor());
        System.out.println("Valor2 (Primitivo): " + valor2);
        int soma = valor1.getValor() + valor2;
        
        System.out.println("Soma = " + soma);
    }
}

Saída (o tipo primitivo manteve seu valor, porém, o objeto foi alterado):

Antes do metodo
Valor1 (Objeto): 0
Valor2 (Primitivo): 10

Dentro do metodo
Valor1 (Objeto): 10
Valor2 (Primitivo): 20
Soma = 30

Depois do metodo
Valor1 (Objeto): 10
Valor2 (Primitivo): 10

Para podermos entender com funciona a passagem de parâmetros em Java, vamos primeiro explorar um pouco as áreas da memória (stack e heap):


Na área STACK ficam as variáveis locais dos métodos que pertencem a um dos 8 tipos primitivos do Java (byte, short, int, long, float, double, boolean e char) e também as referências para os objetos armazenados na área de HEAP.

Na área de HEAP ficam os objetos.

O que aconteceu é que, ao passarmos uma variável (tipo primitivo) como parâmetro para os métodos em Java, esse método recebe uma cópia do valor da variável e, da mesma forma, se passarmos um objeto como parâmetro ele recebe uma cópia do valor da referência desse objeto.

Se alterarmos o valor da variável dentro do método, como é uma cópia, não afetará seu valor externamente. No caso de objetos, ele acessa o objeto na área de HEAP por meio da cópia da referência que recebeu como argumento, que aponta para o mesmo objeto instanciado fora do método, e por isso, uma alteração feita em um objeto dentro do método alterará seu valor fora dele.

OK, por hoje foi isso. Espero que eu tenha sido claro na explicação. Quaisquer dúvidas deixe nos comentários.

Até o próximo.

Nenhum comentário:

Postar um comentário