Introdução
Muitos programadores Java questionam se o Java é passagem por valor ou passagem por referência. Este artigo resume por que o Java é sempre passagem por valor.
Primeiro, o que significa passagem por valor e passagem por referência?
- Passagem por valor: Os valores dos parâmetros do método são copiados para outra variável e então o objeto copiado é passado para o método. O método utiliza a cópia.
- Passagem por referência: Um alias ou referência ao parâmetro real é passado para o método. O método acessa o parâmetro real.
Frequentemente, a confusão em torno desses termos é resultado do conceito de referência de objeto em Java. Tecnicamente, o Java é sempre passagem por valor, porque mesmo que uma variável possa conter uma referência a um objeto, essa referência de objeto é um valor que representa a localização do objeto na memória. As referências de objeto são, portanto, passadas por valor.
Ambos os tipos de dados por referência e os tipos de dados primitivos são passados por valor. Saiba mais sobre tipos de dados em Java.
Além de entender os tipos de dados, também é importante compreender alocação de memória em Java, pois os tipos de dados por referência e os tipos de dados primitivos são armazenados de maneira diferente.
Demonstrando passagem por valor
O exemplo a seguir demonstra como os valores são passados em Java.
O programa de exemplo utiliza a seguinte classe:
public class Balloon {
private String color;
public Balloon() {}
public Balloon(String c) {
this.color = c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
O programa de exemplo a seguir utiliza um método genérico, swap()
, que troca duas variáveis. Outro método, changeValue()
, tenta alterar os valores das variáveis.
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); // referência de memória = 50
Balloon blue = new Balloon("Blue"); // referência de memória = 100
swap(red, blue);
System.out.println("After the swap method executes:");
System.out.println("`red` color value = " + red.getColor());
System.out.println("`blue` color value = " + blue.getColor());
changeValue(blue);
System.out.println("After the changeValue method executes:");
System.out.println("`blue` color value = " + blue.getColor());
}
// Método genérico de troca
public static void swap(Object o1, Object o2){
Object temp = o1;
o1 = o2;
o2 = temp;
}
private static void changeValue(Balloon balloon) { // balão = 100
balloon.setColor("Red"); // balão = 100
balloon = new Balloon("Green"); // balão = 200
balloon.setColor("Blue"); // balão = 200
}
}
Ao executar o programa de exemplo, você obtém a seguinte saída:
OutputAfter the swap method executes:
'red' color value = Red
'blue' color value = Blue
After the changeValue method executes:
'blue' color value = Red
A saída mostra que o método swap()
não trocou os valores de cor dos objetos originais. Isso ajuda a mostrar que Java é passado por valor, já que o método swap()
atua apenas em cópias dos valores de referência de objeto originais.
Este teste do método swap()
pode ser usado com qualquer linguagem de programação para verificar se é passado por valor ou por referência.
O Método de Exemplo swap()
Explicado
Ao utilizar o operador new
para criar uma instância de uma classe, o objeto é criado e a variável contém a localização na memória onde o objeto é salvo.
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
Aqui está uma explicação passo a passo do que acontece quando o método swap()
é executado:
-
Suponha que
red
esteja apontando para a localização de memória 50 eblue
esteja apontando para a localização de memória 100, e que estas sejam as localizações de memória de ambos os objetosBalloon
. -
Quando a classe chama o método
swap()
com as variáveisred
eblue
como argumentos, duas novas variáveis de objeto,o1
eo2
, são criadas.o1
eo2
também apontam para as localizações de memória 50 e 100, respectivamente. -
O trecho de código a seguir explica o que acontece dentro do método
swap()
:public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100 Object temp = o1; // atribui o valor de referência do objeto o1 a temp: temp = 50, o1 = 50, o2 = 100 o1 = o2; // atribui o valor de referência do objeto o2 a o1: temp = 50, o1 = 100, o2 = 100 o2 = temp; // atribui o valor de referência de temp a o2: temp = 50, o1 = 100, o2 = 50 } // método terminado
-
Os valores de
o1
eo2
são trocados, mas como os valores são cópias das localizações de memóriared
eblue
, não há alteração nos valores das coresred
eblue
.
Uma vez que as variáveis contêm a referência aos objetos, é um erro comum assumir que você está passando a referência e o Java é passado por referência. No entanto, você está passando um valor que é uma cópia da referência e, portanto, é passado por valor.
O Método de Exemplo changeValue()
Explicado
O próximo método no programa de exemplo muda o valor da cor do objeto referenciado pela variável blue
:
private static void changeValue(Balloon balloon) { // balão = 100
balloon.setColor("Red"); // balão = 100
balloon = new Balloon("Green"); // balão = 200
balloon.setColor("Blue"); // balão = 200
}
Aqui está uma explicação passo a passo do que acontece dentro do método changeValue()
:
-
A classe chama o método
changeValue()
na variávelblue
que referencia a localização de memória 100. A primeira linha cria uma referência que também aponta para a localização de memória 100. O valor da cor do objeto na localização de memória 100 é alterado para"Vermelho"
. -
A segunda linha cria um novo objeto (com valor de cor
"Verde"
). O novo objeto está na localização de memória 200. Quaisquer métodos adicionais executados na variávelbalão
atuam sobre o objeto na localização de memória 200, e não afetam o objeto na localização de memória 100. A nova variávelbalão
sobrescreve a referência criada na linha 1 e a referência debalão
da linha 1 não está mais acessível dentro deste método. -
A terceira linha altera o valor de cor do novo objeto
Balloon
na localização de memória 200 para"Blue"
, mas não afeta o objeto original referenciado porblue
na localização de memória 100. Isso explica por que a última linha da saída do programa de exemplo imprimeblue color value = Red
, refletindo a alteração da linha 1.
Conclusão
Neste artigo, você aprendeu por que o Java é passado por valor. Continue sua aprendizagem com mais tutoriais de Java.
Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference