pessoal queria tirar uma duvida… lendo o livro da kathy nao entendi muito a página 117 e 118…quando fala sobre passagem por valor e variaveis de referencia a objetos…
bom ela diz que: passagem por valor o metodo chamado nao pode alterar a variavel do chamando e as variaveis de objetos o metodo chamado pode alterar o objeto.
Deu um nó aqui na kbeça de entender exatamente isso ela deu um exemplo meio complicado alguem pode me explicar melhor com um exemplo simples… valeu… obrgiado galera…
Então vamos fazer um eemplo pra ficar mais claro:
[code]public class Teste
{
public static void porValor(int a)
{
a = 100;
}
public static void porReferencia(Date d)
{
d.set(2007,1,1); // acho que não existe esse método, + não sei como mudar a data...rssss
}
public static void main(String[] args)
{
int x = 5;
Date dt = new Date();
// fazer a chamada por valor (x vale 5)
porValor(x);
System.out.println("x = " + x); // x continua valendo 5
// faz a chamada por referência (dt possui a data atual)
porReferencia(dt);
System.out.println(dt.toString()); // agora dt possui a nova data
}
}[/code]
É + - isso…entendeu??
Olha não sei em java! pois não cheguei nessa parte ainda… hehehe
Mas passagem de parâmetro por valor e por referência é o seguinte…
Imagina q vc tem uma variável global… e vc passa ela como parâmetro em uma função.
Se vc passar por valor, ele vai criar uma cópia dessa variável na memoria, e tudo q vc mexer nela, vc vai estar alterando essa cópia, e não a variavel original…
Se vc passar por referência, a função sempre vai apontar pra posição original da variavel na memória, e tudo que vc fizer com akela variável dentro da função, vai alterar sua variável original…
Então, deduzo q em java, se vc passar o parametro do objeto por valor, ele vai criar uma copia do objeto na memoria, e vai trabalhar com essa copia, e se vc passar por referência, ele vai sempre se referenciar ao objeto original!!
Acho q é isso… se tiver errado me corrijam!!!.. xD
Essas dúvidas acontecem muito quando se está aprendendo ponteiros em C/C++. Na verdade o conceito em Java é parecido, mas os ponteiros ficam escondidos, a coisa toda acontece por baixo dos panos. Mas quando estamos lidando com objetos em Java, toda a passagem de objetos como parâmetros para métodos é feita por referência. Passagem por valor (ou cópia) acontece somente com os tipos primitivos. O exemplo do diego2005 mostra isso direitinho.
Passagem por valor: Cria-se uma cópia do tipo primitivo passado. Vc terá duas variáveis na memória, do mesmo tipo e com os mesmos valores.
Quando chamamos o método aumentaInteiro(), teremos dois inteiros na memória, nossa variável número e o parâmetro x dentro do método. Ambos terão o mesmo valor, mas quando é feito x++, essa alteração não ocorre em número, somente no valor passado por cópia.
public void aumentaInteiro(int x){
x++; //lembre-se que um inteiro é um tipo primitivo
}
//...mais código...
int numero = 5;
System.out.println(aumentaInteiro(numero));
//a saída continua sendo 5, não 6...
Se a passagem for feita por referência, passamos apenas o endereço de memória do objeto, assim continuamos tendo apenas 1 objeto alocado. Uma alteração em qualquer característica do objeto é refletida em qualquer local do código onde este objeto seja utilizado.
public void alteraString(String s){
//lembre-se de que em Java String é uma classe!
s = "blablabla";
}
//... mais código...
String palavra = "blebleble";
System.out.println(alteraString(palavra));
//a saída aqui será "blablabla", pois o objeto foi alterado pelo método.
Abraço!
rpz… meio confuso heim… deu ± para ter ideia… mais valeu pela dica… ai vou tentar procurar mais… se cair muito questoes dessa no exame to morto…
Camilo vou complementar os conceitos do Cassio,
a memória em praticamente todas as linguagens são dividias em três segmentos: código, heap e stack.
A área de código é onde fica os programas propriamente ditos.
O heap e o stack em java trabalham da seguinte forma:
Todos os tipos primitivos são alocados no stack (como se fossem variáveis locais e são).
Todos os objetos sempre são alocados no heap e a variável que os referência no stack.
Por exemplo:
no exemplo, a variável dt é local ao método main e está armazenada no stack, mas o objeto “representado” por ela está no heap. Funciona examente como o Cassio falou, na realidade todo objeto tem uma variável local (ponteiro) que aponta para um objeto.
Pois bem, quando é invocado o método porReferencia é criado mais uma entrada na pilha de execução e uma cópia da variável local no stack (mas esta variável aponta para o mesmo endereço do objeto que está no heap). Quando você fizer uso de um método ou de uma modificação no objeto ele irá modificar no heap e não na local, por isso quando o objeto retorna ele tem seu conteúdo modificado.
Apesar do java não “usar” os ponteiros explicitamente, isto explica por exemplo a funcionalidade do código abaixo:
public static void main(String[] args) {
StringBuffer buf = new StringBuffer("versão 1");
chamaMetodoPorReferencia1( buf );
System.out.println( buf );
chamaMetodoPorReferencia2( buf );
System.out.println( buf );
}
public static void chamaMetodoPorReferencia1(StringBuffer x) {
x.append("\npassou por aqui.");
}
public static void chamaMetodoPorReferencia1(StringBuffer x) {
x = new StringBuffer("versão 2");
}
A saída em tela será:
Veja que neste ponto o Cassio se equivocou, Por quê???
como eu te falei, apesar de objeto ser passado por referência, a variável que recebe o endereço do objeto é local e quando criamos um novo objeto, alocamos um novo endereço e este novo endereço e passado para a variável local do método. Quando ele for finalizado, as variáveis locais são descartadas e os objetos?
Bom ai entra o gc, ele verifica que tem objetos alocados no heap mas que não possui nenhuma variável local apontando para ele, logo ele pode liberar a memória… está é a mágica do gc.
falou.
[editado]
o equivo do Cassio foram dois, a questão da passagem de parâmetros acima e o fato do método que ele utilizou no System.out ser do tipo void.
(desculpe meu velho, não pude deixar passar esta).
[quote=Dieval Guizelini]Camilo vou complementar os conceitos do Cassio,
a memória em praticamente todas as linguagens são dividias em três segmentos: código, heap e stack.
A área de código é onde fica os programas propriamente ditos.
O heap e o stack em java trabalham da seguinte forma:
Todos os tipos primitivos são alocados no stack (como se fossem variáveis locais e são).
Todos os objetos sempre são alocados no heap e a variável que os referência no stack.
Por exemplo:
no exemplo, a variável dt é local ao método main e está armazenada no stack, mas o objeto “representado” por ela está no heap. Funciona examente como o Cassio falou, na realidade todo objeto tem uma variável local (ponteiro) que aponta para um objeto.
Pois bem, quando é invocado o método porReferencia é criado mais uma entrada na pilha de execução e uma cópia da variável local no stack (mas esta variável aponta para o mesmo endereço do objeto que está no heap). Quando você fizer uso de um método ou de uma modificação no objeto ele irá modificar no heap e não na local, por isso quando o objeto retorna ele tem seu conteúdo modificado.
Apesar do java não “usar” os ponteiros explicitamente, isto explica por exemplo a funcionalidade do código abaixo:
public static void main(String[] args) {
StringBuffer buf = new StringBuffer("versão 1");
chamaMetodoPorReferencia1( buf );
System.out.println( buf );
chamaMetodoPorReferencia2( buf );
System.out.println( buf );
}
public static void chamaMetodoPorReferencia1(StringBuffer x) {
x.append("\npassou por aqui.");
}
public static void chamaMetodoPorReferencia1(StringBuffer x) {
x = new StringBuffer("versão 2");
}
A saída em tela será:
Veja que neste ponto o Cassio se equivocou, Por quê???
como eu te falei, apesar de objeto ser passado por referência, a variável que recebe o endereço do objeto é local e quando criamos um novo objeto, alocamos um novo endereço e este novo endereço e passado para a variável local do método. Quando ele for finalizado, as variáveis locais são descartadas e os objetos?
Bom ai entra o gc, ele verifica que tem objetos alocados no heap mas que não possui nenhuma variável local apontando para ele, logo ele pode liberar a memória… está é a mágica do gc.
falou.
[editado]
o equivo do Cassio foram dois, a questão da passagem de parâmetros acima e o fato do método que ele utilizou no System.out ser do tipo void.
(desculpe meu velho, não pude deixar passar esta).
[/quote]
Que nada Diego, eu realmente vacilei em ter colocado o método dentro do System.out.println(). Deveria ter chamado o método e depois ter usado os argumentos como parâmetros para o System.out…
Mas espero que de um jeito ou de outro o camilo tenha entendido o esquema das referências
po valeu galera… entao referencia a objetos alteração em qualquer parte é refletida a quem se ele está se referindo e passagem por valor é apenas uma copia mais alteração nao reflete em quem recebe esse valor seria ± isso?
É mais ou menos isso sim camilo…
Pra entender melhor vc tbm poderia dar uma olhada em como isso funciona em outras linguagens, no caso utilizando ponteiros. Java não tem ponteiros (não explicitamente), mas para o lance da diferença entre referência e cópia entender ponteiros vai te ajudar bastante.
Ponteiros existem, por exemplo, em C/C++ e Pascal. Se vc programar em Delphi, por exemplo, tvz já tenha visto algo de ponteiros em Pascal…
Abraço!