Passagem de parâmetros em Java

Ontem no grupo de Computação Gráfica na UFRGS a gente teve uma bela discussão sobre passagem de parâmetros em Java. O interessante é que todo mundo sabia como funciona o mecanismo, só que uns chamavam de um jeito e outros (no caso, só o Pamplona, hehehe) chamavam a mesma coisa de outro nome. Por exemplo:

No caso de uma variável de um tipo primitivo, ela é passada por valor (isto é, por cópia).

No caso de uma variável contendo um objeto, o ponteiro pro objeto, ou melhor, a referência (assim costuma-se dizer em Java) é passada por valor.

E aqui havia a bifurcação:

Eu e todo mundo dizíamos, que se a referência ao objeto é passada, o objeto é passado por referência, então! Simples e lógico…

Já o Pamplona concluía que então tudo era passado por valor, já que a referência ao objeto era passada por valor, do mesmo jeito que os tipos primitivos. Faz sentido também, mas eu ainda acho que passar uma referência é passagem por referência. :)

Não me lembrei de perguntar: “Se isso aí não é passagem por referência, o que é passagem por referência então?”. Bom, imagino que a resposta seria: “Passagem por referência é passar a própria referência por referência”. Pra mim isso o nome disso é exatamente o que eu escrevi: passagem de referência por referência. Confuso? Acho que não! (o outro caso era passagem de objeto por referência, só pra relembrar) :D

No fim das contas, eu acho que o programador não pode deixar de saber que existe tanto o objeto quanto sua referência. São 2 expressões (passagem por valor e passagem por referência) pra expressar 3 conceitos (valor, referência por valor e referência por referência). Não tem como explicar melhor as coisas sem dar a explicação completa. Dizer que é tudo por valor não explica bem todos os casos, e dizer que tipos primitivos são passados por valor e objetos são passados por referência também é uma explicação meio incompleta (fica faltando: “é a referência ao objeto que é passada por valor”).

Agora, não é incrível que uma linguagem tão usada como o Java tenha apenas essas duas maneiras de passar parâmetros? Bah, isso é uma coisa básica, falta uma passagem por referência pra tipos primitivos… Como é que eu vou criar uma função pra trocar dois valores (fazer um “swap“)? Não dá! Em C++, tem a função std::swap. Ela é engraçada pois, apesar de ser um conceito simples, precisa usar um recurso avançado da linguagem: templates (fora a indispensável passagem por referência™, é claro). Mas funciona. E Python, Lua e outras linguagens, nem precisam dessa função, basta fazer algo como (em Lua): y, x = x, y. Pronto, x e y estão trocados… Só pra comparar, em C o negócio também é problemático, não sei se pior ou melhor que Java. C# e D têm passagem por referência, cada um ao seu jeito.

Anúncios

5 pensamentos sobre “Passagem de parâmetros em Java

  1. No Java, toda passagem de parâmetro é por valor. Passagem por referência seria algo do tipo

    void swap(Object a, Object b) {
    Object c = a;
    a = b;
    b = c;
    }

    a = “1”;
    b = “2”;
    swap(a,b);
    System.out.println(a + b);

    // passagem por valor: “12”
    // passagem por referência: “21”

    Pascal tem um esquema desse tipo, quando você declara um parâmetro com ‘var’, acho. C, como Java, faz apenas passagem por valor. A diferença é que a linguagem C possui ponteiros, facilmente acessíveis. então, a chamada a uma função swap em C ficaria assim:

    swap(&a, &b)

    explicitando a passagem dos (valores dos) ponteiros para a e b.

  2. Sim, em Pascal, é “var” que se usa. Em C++ é “&”, em C# é “ref” e em D é “inout”.
    Em C, o cara sofre muito pra fazer isso, hehehe. Tem que receber os ponteiros, e ficar des-referenciando eles. É fácil e esquecer um asterisco ou colocar um asterisco a mais…

  3. Ah, esqueci de um ponto:

    Dá pra dizer que a passagem de parâmetros no Java é “por atribuição”. Aí é “só” explicar como a atribuição funciona que a passagem de parâmetros também será explicada! heehehe.
    Por esse ponto de vista, dizer que “tudo é por valor” faz um pouco mais de sentido. Toda a passagem de parâmetros é por valor, desde que já se saiba como funciona a atribuição entre primitivos e entre objetos…

  4. isso e o mesmo que no teatro que alguem encerna uma personagem nem por iso na sua saida do teatro deixa de ser ele mesmo todas as alteracoes sao feitas na sua copia

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s