Entenda que os parâmetros são passados por valor e não por referência.

Extraído do site: www.portaljava.com


Existe um falso conceito muito comum, de que os parâmetros em java são passados por referência. Isso não acontece. Os parâmetros são passados por valor. O erro surge do fato de que todas as variáveis de objeto são referências de objeto. Isso leva a alguns resultados inesperados se você não entender exatamente o que está acontecendo. Por exemplo:

import java.awt.Point;

class PassByValue {
   
 public static void modifyPoint(Point pt, int
j) {
        pt.setLocation(5,5);                                       
 // 1

        j = 15;
        System.out.println("
During modifyPoint = " + " pt = " + pt + " and j = " + j);
    }
    
    
public static void
main(String args[]) {
        Point p =
new Point(0,0);                               // 2

        
int i = 10;
        System.out.println("
Before modifyPoint " + " p = " + p + " and i =
" + i);
    
        modifyPoint(p, i);                                           
 // 3

        System.out.println(
"After modifyPoint " + "p = " + p + "and i =
" + i);
    }
}

Este código cria um objeto Point, inicializado em (0,0), e atribui à variável de referência de objeto p em // 2. Depois ele atribui ao tipo primitivo int i o valor 10. O método sataticModifyPoint é então chamado em // 3, passando p e i. O método modifyPoint chama o método setLocation no primeiro parâmetro, pt, alterando seu local para (5,5). Além disso, o segundo parâmetro, j, recebe o valor 15. Quando o métod modifyPoint retorna, o método main imprime os valores para p e i. Qual é a saída desse código e por que?

        A saída desse código é a seguinte:

        Before modifyPint p = java.awt.Point[x=0,y=0] and i = 10
        During modifyPoint pt = java.awt.Point[x=5,y=5] and i = 15
        After modifyPoint p = java.awt.Point[x=5,y=5] and i =10

Essa saída mostra que o método modifyPoint altera o objeto Point criado em //2, mas não o int i. Em main, i recebe o valor 10. Os parâmetros são passados por valor; portanto, uma cópia de i é passada para o método modifyPoint.
Esses método muda o valor da cópia para 15 e retorna. O valor original, i em main, não é alterado.
Por constraste, você poderia pensar que o objeto Point criado em //2 não é modificado9 pelo método modifyPoint. Afinal, o Java passa parâmetros por valor.
Portanto, quando modifyPoint é chamado com o objeto Point criado em //2, é feito uma cópia para o método modifyPoint trabalhar com ela. As mudanças no objeto Point em modify não são refletidas em main, pois existem dois objetos diferentes. Certo? Errado!
Na realidade, modifyPoint está trabalhando com uma cópia de uma referência de objeto Point, e não com uma cópia do objeto Point. Lembre-se de que p é uma referência de objeto e que Java passa parâmetros por valor. Mais especificamente, o Java passa referências de objeto por valor. Quando p é passado de main para modifyPoint uma cópia do valor de p, a referência, é passada. Portanto, o método modifyPoint está trabalhando com o mesmo objeto, mas por meio de alias, pt. Depois de entrar em modifyPoint, mas antes da execução do código em //1.


Portanto, depois que o código em //1 é executado, o objeto Point é alterado para (5,5). E se você quiser não permitir alterações para o objeto Point em metodos como o modifyPoint? Existem duas soluções para isso:

- Passe um clone do objeto Point par ao método modifyPoint.
- Torne o objeto Point imutável.

Dúvidas, sugestões, visitem o tópico que eu criei para este assunto:
http://www.portaljava.com/home/modules.php?op=modload&name=Forums&file=viewtopic&topic=174&forum=10



Por hoje é isso!
Até logo;

Dalton M. de Camargo
dalton@portaljava.com