| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 00:59:55
|
renzonuccitelli
GUJ Master
Membro desde: 17/09/2008 12:58:32
Mensagens: 1133
Offline
|
Outro dia um amigo meu me perguntou se a passagem de parametro em Java é feita por referência. Respondi prontamente que sim, como já havia escutado várias vezes de muitas pessoas. Então ele colocou o seguinte código pra rodar:
Para minha supresa e a dele, o resultado impresse foi 1 1 0. Assim, se a passagem fosse mesmo feita por referência, nós o resultado a ser impresso deveria ser 0 0 0. Assim, chegamo a conclusão que o que dizem não é correto. A passagem seria feita por valor, e os métodos do objeto em si seriam passados como referência. Mas gostaria de saber do pessoal que manja de Java pudesse dar uma explicação melhor para isso, se possível.
|
Renzo Nuccitelli
Engenheiro de Computação - ITA
http://nuccitec.com.br/
http://blog.nuccitec.com.br/
http://jcoltrane.sf.net
http://jfera.nuccitec.com.br/
http://code.google.com/p/webapp-ce/
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 01:10:02
|
Valder Olmo Corrêa
JavaGuru
![[Avatar]](/images/avatar/8760f3931e4da88677b3b650b5743f89.jpg)
Membro desde: 29/12/2007 17:22:53
Mensagens: 213
Localização: São Paulo
Offline
|
renzonuccitelli, sempre ouvi dizer que a passagem de parâmetros em java é sempre por valor, pois não há passagem por referência em Java.
Sempre pensei também que em C houvesse passagem por referência, mas não há, o que o C faz é passar um ponteiro para que a variável apontada pelo ponteiro seja modificada.
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 01:15:04
|
renzonuccitelli
GUJ Master
Membro desde: 17/09/2008 12:58:32
Mensagens: 1133
Offline
|
Sim, mas isso de passar o ponteiro é que faz ser a passagem por ref, o ponteiro é a referência, ou seja, qdo vc mudar o valor do argumento, mudará o valor da variaável que foi passada.
Te digo que sempre ouvi que a passagem em Java era feita por ref e nao por valor...
|
Renzo Nuccitelli
Engenheiro de Computação - ITA
http://nuccitec.com.br/
http://blog.nuccitec.com.br/
http://jcoltrane.sf.net
http://jfera.nuccitec.com.br/
http://code.google.com/p/webapp-ce/
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 02:50:45
|
dm_thiago
JavaEvangelist
![[Avatar]](/images/avatar/a829b6def307bd357011e57e5d6a635d.png)
Membro desde: 14/02/2007 04:23:55
Mensagens: 305
Offline
|
A passagem de objetos é SIM feita por referência.
renzonuccitelli wrote:
No seu método main você criou um objeto Cobaia e o atribuiu a variável cobaia, ou seja, a variável cobaia agora aponta para o endereço do objeto que você acabou de criar.
Quando você chama um método e passa um objeto como parâmetro, você passa o endereço dele para o método. Então quando você chamou o método alterarCobaiaCriandoNova, a sua variavel cobaia (na assinatura do método) recebeu o endereço do objeto que você havia criado no metodo main. Então agora você tem duas variáveis apontando para o mesmo objeto, a do método main e aquela do seu método alterarCobaiaCriandoNova.
Caso você faça alguma alteração NO OBJETO (acessando diretamente os atributos ou usando métodos de acesso), você verá que não importa qual variável você use para imprimir o valor, ambas irão mostrar o mesmo valor. Agora, quando você criar um novo objeto, e atribuí-lo a uma variável, você só mudou o endereço para onde aquela variável apontava, e não sobrescreveu o objeto que era apontado pela variável. Então, se antes as duas variáveis apontavam para o mesmo objeto, agora uma irá apontar para um e a outra para o outro.
Um exemplo real de como isso funcionaria:
1) Pense que o seu dedo é uma variável, que pode apontar para qualquer coisa (seria como um "Object dedo;")
2) Agora aponte para uma tomada (Atribuimos um objeto para a variavel dedo, no java seria um "dedo = new Tomada();")
3) Agora pegue o dedo do seu amigo e aponte para a mesma tomada ("Object dedoAmigo = dedo;")
4) Agora, pinte você a tomada de branco ("dedo.setColor(Color.WHITE);")
5) Veja, a tomada para a qual você e seu amigo estão apontando agora é branca!
6) Agora mande seu amigo pintá-la de vermelho ("dedoAmigo.setColor(Color.RED);")
7) E agora, vocês dois estão apontando para uma tomada vermelha.
Para completar a simulação, você agora aponte para uma outra tomada ("dedo = new Tomada();")
9) Agora pinte a tomada que você está apontando de azul ("dedo.setColor(Color.BLUE);")
Repare, seu amigo continua a apontar aquela antiga tomada, que está vermelha, e você agora aponta uma tomada azul. Vocês deixaram de possuir a mesma referencia quando você criou uma nova tomada para você (no passo .
Entendeu o que aconteceu no seu programa de teste? A partir do momento que você criou novos objetos, você perdeu a antiga referencia, que tinha sido criada no metodo main, então a variável do seu método main continuou apontando para a variável antiga, e não a que você criou nos métodos.
E é assim que funciona a passagem por referência. Espero ter sido claro
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 08:27:54
|
thegoergen
Virtual Machine Man
![[Avatar]](/images/avatar/7da9e0bb90d7f5b27e9af974fe437abf.jpg)
Membro desde: 24/09/2007 09:44:03
Mensagens: 583
Localização: Estrela/RS
Offline
|
Perfeito dm_thiago.
Realmente agora eu consegui entender, estava quebrando a cabeça interpretando o código da Cobaia e do Mito.
Na verdade, eu nunca tinha parado pra pensar sobre o assunto...
|
"A preguiça de pensar é a maior burrice de uma pessoa." (Diego Inácio Goergen)
CV: Diego Inácio Goergen
Administrador da UNISCWiki e Medicina UNISC |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 08:30:14
|
jingle
Virtual Machine Man
Membro desde: 04/10/2006 20:40:08
Mensagens: 642
Localização: Canoas/RS
Offline
|
realmente... muito bom exemplo, não deixa brecha para duvidas.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 08:39:38
|
lcegatti
JavaGuru
![[Avatar]](/images/avatar/a0f15903fa20c9b96994cea76d690fab.jpeg)
Membro desde: 29/01/2007 13:43:20
Mensagens: 218
Localização: São Paulo
Offline
|
Muito bom mesmo dm_thiago, mando bem nessa.
[]'s
|
SCJP
Caia na Real |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 09:20:26
|
wagnerfrancisco
JavaGuru
![[Avatar]](/images/avatar/8557f7303f1355575b6e95d411c9cead.jpg)
Membro desde: 02/10/2007 10:05:02
Mensagens: 243
Localização: Criciúma / SC
Offline
|
Se não me engano, segundo o Head First: Java, a passagem é feita SEMPRE por VALOR.
Ou seja, tu envia uma cópia do conteúdo da tua "variável". No caso de primitivos, tranquilo. É fácil observar, já que o valor não é alterado no método que recebe o valor por parâmetro. No caso de objetos, a confusão acontece porque o conteúdo da variável não é a instância do objeto, e sim o endereço desta instância. Quando você manda um objeto por parâmetro, você passa o conteúdo dele (por valor, cópia). Só que o conteúdo é o endereço. Desse modo, você cria uma outra variável que recebe o mesmo endereço. Concluindo, a cópia é por valor.
Falou.
|
http://wagnermezaroba.blogspot.com |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 09:48:43
|
rafaelglauber
GUJ Master
![[Avatar]](/images/avatar/e9abec5e32203998211653b45023be1c.jpeg)
Membro desde: 07/09/2007 23:05:20
Mensagens: 1065
Localização: Feira de Santana
Offline
|
Oi,
E é assim que funciona a passagem por referência. Espero ter sido claro
Vejo que todo mundo gostou da explicação, não concordo com ela e a sun também não, logo se alguém tá pensando em fazer certificação java nunca respondam isso, toda passagem é por valor e não por referência ou qualquer outra coisa. A diferença quando tratamos de objetos é que a cópia não é do objeto, mas sim da referência ao objeto.
ps. não estou dizendo que a explicação não é correta, ou que não foi boa, só não tá de acordo com as documentações da sun e dos materiais de certificação.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 12:23:59
|
renzonuccitelli
GUJ Master
Membro desde: 17/09/2008 12:58:32
Mensagens: 1133
Offline
|
Rafael, sua explicação sobre a cópia da referência fica melhor mesmo. Porque a outra tb não gostei não não. Em C, se vc recebe o valor por referência (o ponteiro) e vc apota ele para outro lugar, o valor que vc tinha passado muda tb, o q não aconteceu com o exemplo. Sendo a cópia da refêrencia, aí sim, fica explicado o funcionamento...
Vlw galera, vivendo e aprendendo...hehe
|
Renzo Nuccitelli
Engenheiro de Computação - ITA
http://nuccitec.com.br/
http://blog.nuccitec.com.br/
http://jcoltrane.sf.net
http://jfera.nuccitec.com.br/
http://code.google.com/p/webapp-ce/
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 13:10:32
|
souzaJr
Debugger
![[Avatar]](/images/avatar/41f68228d0fc3e3414dfabe7fc3631d0.jpg)
Membro desde: 04/08/2008 12:28:29
Mensagens: 53
Offline
|
Quando você chama um método e passa um objeto como parâmetro, você passa o endereço dele para o método.
dm_thiago,
você não passa o endereço do objeto para o método, o que é passado é uma cópia (valor) do endereço (referência), e é por isso que é comum dizer que toda passagem de parametros em Java é sempre por valor (seja por valor de referência - para objetos, ou valor mesmo - tipo primitivo).
Assim, você pode alterar o estado (atributos) do objeto para qual a referência (a cópia) adquirida pelo método aponta, mas não a própria referência. Você fica com duas referência e um só objeto...
Repare, seu amigo continua a apontar aquela antiga tomada, que está vermelha, e você agora aponta uma tomada azul. Vocês deixaram de possuir a mesma referencia quando você criou uma nova tomada para você
É por isso que isso acontece...porque você não pode alterar a referência do seu colega...pq você não a tem...você só tem a cópia...e faz o que quiser com ela (Pode apontar para onde quiser).
Até mais.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 13:30:15
|
Andre Brito
JWizard
Membro desde: 21/07/2007 17:44:31
Mensagens: 2485
Localização: Paraná
Offline
|
Essa discussão nunca acaba. Já teve alguma coisa parecida aqui eu acho. Apesar disso, é uma coisa muito importante. Até me lembro de uma coisa que acontece em meados de Fevereiro. Eu estava (ainda estou) em um projeto de um AG Hibridizado Fuzzy. Temos, mais ou menos, míseras 20, 30 classes e estão bastante acopladas. O resultado final não era confiável porque ele foi feito em partes (um faz um, outro faz outra parte) e nos deparamos justamente com esse problema: chamávamos um método e mudávamos o valor do parâmetro. Quando fomos debuggar, BUM! Tudo estava mudando mesmo... até que tivemos que fazer um clone() em muitas classes. Aprendemos com as "cagadas" que estavam acontecendo. Porém, em algumas situações, utilizar e mudar o parâmetro parece que não acarreta em outro erros semânticos... sei lá hein... essa questão, por mais que muito discutida, ainda não bate bem.
|
Como organizar o GUJ.
Meu Twitter.
Meu blog.
Future proofing means making code easy to change, not trying to anticipate every possible way your code might need to change. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 04/10/2008 22:43:54
|
lcegatti
JavaGuru
![[Avatar]](/images/avatar/a0f15903fa20c9b96994cea76d690fab.jpeg)
Membro desde: 29/01/2007 13:43:20
Mensagens: 218
Localização: São Paulo
Offline
|
Essa discussão nunca acaba.
rsrs verdade
Enfim ... isso acabou com minhas dúvidas sobre o assunto, talvez ajude.
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
[]'s
This message was edited 1 time. Last update was at 04/10/2008 22:45:39
|
SCJP
Caia na Real |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 05/10/2008 06:15:33
|
s4nchez
Virtual Machine Man
![[Avatar]](/images/avatar/bef4d169d8bddd17d68303877a3ea945.jpg)
Membro desde: 05/06/2006 11:35:55
Mensagens: 673
Localização: London, UK
Offline
|
Aqui tem outro artigo explicando como java funciona:
http://www.javaranch.com/campfire/StoryPassBy.jsp
Java is pass-by-value.
For primitives, you pass a copy of the actual value.
For references to objects, you pass a copy of the reference (the remote control).
You never pass the object. All objects are stored on the heap. Always.
|
Ivan Sanchez | coding dojo | blog | twitter |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/01/2009 19:48:32
|
Marcio Duran
GUJ Master
![[Avatar]](/images/avatar/df0e19d29493ef2136fc3e2fc029c054.jpg)
Membro desde: 23/01/2008 11:14:35
Mensagens: 1905
Offline
|
renzonuccitelli wrote:(..........)................... A passagem seria feita por valor, e os métodos do objeto em si seriam passados como referência. Mas gostaria de saber do pessoal que manja de Java pudesse dar uma explicação melhor para isso, se possível.
Exite tipos de referência, os quais incluem recursos que permitem a manipulação de objetos e matrizes(arrys) em uma única variável.
Todos os dados manipulados em java fazem parte de alguma classe, com exceção dos dados primitivos da linguagem (int, long, float, double, boolean, char etc...)
Outro ponto é que a instância de classe(ou seja, objeto) criada é sempre manipulada por meio de algo que a referencie - no caso, as variáveis declaradas no programa.Para isso, essas variáveis se utilizam de possibilidade de fazer referência usando o endereço da instância.Esse endereço é atribuído a alguma variável declarada, que passa a apontar para a instancia.
|
Consultor Open Source
Comunidade JavaLivros
Twitter Comunidade JavaLivros
Novo Blog do MiddleHeaven |
|
|
 |
|
|