Desculpe por criar mais um tópico falando a respeito do assunto, porém, apesar de ler um pouco, minhas dúvidas não foram sanadas…
Li que, quando um objeto é passado como parâmetro, na realidade, ele não é passado, é enviado o valor da referência do mesmo.
Sendo assim, é correto dizer que ao manipular meu parâmetro formal o qual recebeu a referência de meu parâmetro real, estaria, assim, manipulando o parâmetro real, e não apenas uma cópia do mesmo (como ocorre com os tipos primitivos)?
Se for este o caso, então Java só passa parâmetros por valor devido ao fato de uma variável de objeto nunca armazenar o próprio objeto, mas somente uma referência? Então mesmo que passe uma referência de algum objeto, devo “classificar” esta passagem como passagem por valor, pois, o valor de uma variável, em Java, é uma referência? Sendo assim, posso considerar que eu não possuo acesso direto aos objetos, porém, àpenas referências?
Perdão se não consegui expressar minha reflexão de forma clara, está tudo muito confuso o.O Gostaria da opnião de vocês se o que eu escrevi foi tudo besteira (imagino que bem possivel que isso acontessa ‘-’) ou se “estou no caminho certo”…
Certamente, os objetos são referenciados, toda vez que você utiliza o (new) uma reserva de memória para o Objeto é criada no heap para poder ter sua referência, já um dado primitivo, que tem seu tamanho fixo, ele reserva um tanto de espaço na memória para que seja atribuído um valor a ele.
Fiz uma ilustração para tentar explicar melhor:
Encare o tipo primitivo como um copo, ele tem um tamanho fixo e pode ser enchido e esvaziado.
Quando você faz pessoa1 = pessoa2 você está apenas passando a referência, pois para criar um novo objeto, você teria que utilizar o new, ou clone() da interface Cloneable, porém teria que manualmente (substituindo o método clone()), fazer a clonagem do objeto. Ou utilizando de reflexão, mas não vem ao caso.
Quando um objeto está sem referência alguma, o Garbage Collector (GC) remove tal objeto do heap.
[quote=pb600]Certamente, os objetos são referenciados, toda vez que você utiliza o (new) uma reserva de memória para o Objeto é criada no heap para poder ter sua referência, já um dado primitivo, que tem seu tamanho fixo, ele reserva um tanto de espaço na memória para que seja atribuído um valor a ele.
Fiz uma ilustração para tentar explicar melhor:
Encare o tipo primitivo como um copo, ele tem um tamanho fixo e pode ser enchido e esvaziado.
Quando você faz pessoa1 = pessoa2 você está apenas passando a referência, pois para criar um novo objeto, você teria que utilizar o new, ou clone() da interface Cloneable, porém teria que manualmente (substituindo o método clone()), fazer a clonagem do objeto. Ou utilizando de reflexão, mas não vem ao caso.
Quando um objeto está sem referência alguma, o Garbage Collector (GC) remove tal objeto do heap.
Acho que você já sabe disso tudo.[/quote]
Se eu, segundo seu exemplo, alterar o valor de pessoa1, é criada uma cópia do objeto no heap para pessoa2? Assim, não há alteração em seu valor?
Por exemplo:
pessoa1 = new Pessoa(“Nome do cidadão”);
pessoa2 = pessoa1; //Logo, pessoa2 possui o mesmo nome.
pessoa1.setNome(“Outro nome”); //pessoa2 não altera seu nome, certo? então ela deveria ter a referência de outro objeto no heap, assim não recebe as alterações feitas em pessoa1?
No Java, não existe o conceito de uma variável representar diretamente um objeto. No caso de linguagens como o C++ ou o C#, você pode ter uma variável de objeto/struct que não representa uma referência, e que fará cópias para permitir passagens de parâmetro por valor. No Java, a variável que aponta para o objeto é sempre uma referência. Passa-la por parâmetro irá copiar a referência.
É equivalente a usar ponteiros no C++ (embora em C++, isso também seja chamado de passagem por referência).
Como uma atribuição de Objetos (objeto1 = objeto2) são passadas apenas referências, se eu associar, por exemplo, o objeto1 à um WeakReference, o objeto2 será afetado?
Exemplo:
[code]private Map<Byte, Objeto> colecoes = new TreeMap(); //Mapa de listas
transient private byte colecaoCorrente; //Marca qual lista estamos alterando
protected void novaColecao() { //Adiciona uma nova lista ao mapa
List<Element> a = new ArrayList();
colecaoCorrente = (byte)colecoes.size();
colecoes.put(colecaoCorrente, a);
}
public void injectNode(Element elemento) {
WeakReference<List> weakList;
List<Element> a;
a = colecoes.get(colecaoCorrente);
weakList = new WeakReference(a); //É guardada apenas a referencia da lista 'a' ou também de 'colecoes.get(colecaoCorrente)' na WeakReference?
a.add(elemento);
colecoes.put(colecaoCorrente, a); //Mesmo com a refência strong de 'colecoes', a lista 'a' pode ser varrida pelo garbage collector? Gostaria de saber também se cometi muitos erros neste trecho-exemplo (alguns tenho certeza que sim :])
}[/code]
Obviamente que não. O garbage collector nunca remove um objeto com uma strong reference apontando para ele.
Weak ou Soft references não conseguem segurar o objeto se estiverem apontando para ele sozinhas. Ou seja, se houver n weaks apontando para o objeto, e nenhuma Strong, aí sim, ele está sujeito a garbage collection.
[quote=ViniGodoy]Obviamente que não. O garbage collector nunca remove um objeto com uma strong reference apontando para ele.
Weak ou Soft references não conseguem segurar o objeto se estiverem apontando para ele sozinhas. Ou seja, se houver n weaks apontando para o objeto, e nenhuma Strong, aí sim, ele está sujeito a garbage collection.[/quote]
Então mesmo que eu atribua um objeto A a um B, e utilize uma WeakReference neste B, já que B possui a mesma referência que A, o WeakReference se torna inútil? (o GC não removerá nenhum objeto do Heap)
A propósito, outra pergunta:
List<Element> a;
a = colecoes.get(colecaoCorrente);
a.add(elemento);
O objeto ‘List a’ recebe a referência de uma outra List dentro da variável ‘colecoes’ e, ao utilizar o método ‘a.add(elemento)’, como ambos referênciam o mesmo local em memória, para não alterar o valor recebido de ‘colecoes.get()’, a JVM realiza uma cópia do objeto e faz as alterações? Ou o objeto proveniente de ‘colecoes.get()’ é alterado também?