Oi wldomiciano, muito obrigado pela sua resposta e pelo seu tempo.
Eu sei que a ideia é nao ter classes “muito grandes” mas imagine uma classe com muitos atributos, eu teria que escrever “this.abritubo = p.atributo;” inumeras vezes.
Se a classe tiver 20 atributos, tenho que ficar repetindo codigo.
A intencao do swap_clone era passar o objeto inteiro de uma vez so, ao inves de codificar atributo por atributo. E se eu precisasse adicionar um novo atributo na classe, eu precisaria lembrar de adiciona-lo nos metodos. Para evitar essas duas situacoes eu estou tentando criar o swap_clone.
Como eu poderia fazer isso?
public class People implements Cloneable {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public People Clone() throws CloneNotSupportedException
{
return (People) super.clone();
}
}
Obrigado pelo exemplo, mas acho que ainda nao é bem isso…
No meu exemplo de estudo eu crio 2 objetos:
“P1 = Lovelace” e “P2 = Tesla”
e depois de executar o método SWAP eu quero inverter isso
“P1 = Tesla” e “P2 = Lovelace”
Seria como “trocar de lugar as informacoes”.
No meu primeiro exemplo eu ja tinha conseguido atraves do medoto “swap_correct”
mas nesse exemplo eu tenho que referenciar atributo por atributo. Existe alguma forma que nao seja fazer a referencia atributo por atributo?
Vc não vai conseguir escapar de copiar atributo por atributo.
Imagine que além de ter 20 atributos, sua classe possui atributos mais complexos.
O método clone padrão faz apenas copias simples e classes mais complexas requerem que vc sobreescreva este método para fazer uma clonagem adequada.
Vc teria que especificar no clone como clonar cada atributo.
Acredito uma possível forma de automatizar o processo seja usando Reflection.
Além disso, no Java, é impossível alterar a identidade de um objeto. Imagine o seguinte exemplo hipotético:
public static void main(String... args) {
Person p1 = new Person();
Person p2 = new Person();
Person temp1 = p1;
Person temp2 = p2;
System.out.println(temp1 == p1); // true
System.out.println(temp2 == p1); // false
System.out.println(temp1 == p2); // false
System.out.println(temp2 == p2); // true
Person.swap(p1, p2);
System.out.println(temp1 == p1); // continua true
System.out.println(temp2 == p2); // continua true
}
Usando o exemplo acima, para obter uma saida diferente da esperada, vc precisaria de uma forma de modificar o conteúdo das variáveis p1 e p2 de dentro do método swap e Java não nos fornece este acesso.
Em C ou C++ esse tipo de coisa é possível com ponteiros para ponteiro, mas em Java não.
Este experimento, vc está se baseando em quê para realizá-lo? Tem algum exemplo de uso de real ou algo assim? Se vc explicar melhor, talvez haja uma saida mais adequada.
Java manipula objetos por referência e todas as variáveis não-primitivas são referências.
Entretanto Java não passa argumentos de métodos por referência e sim por valor, na verdade ele passa uma cópia da referência, por isso é considerado passagem de parâmetro por valor (referência aqui).
Então você não vai conseguir escrever um método que troque a referência de dois objetos passados por parâmetro.
Vais ter que fazer o swap dessa forma:
Opa, muito obrigado pela explicaçao. Agora ficou muito mais claro.
Nao é um caso de uso real, apenas estudos mesmo.
Talvez o Reflection seja uma saida, apesar da complexidade de implementacao para um caso tao simples desse vale o aprendizado. =)
Obrigado pelo exemplo staroski =)
Obrigado mais uma vez galera.
Topico encerrado e duvida esclarecida =)
No C# não sei, mas no C e no C++ existem as duas formas, vai depender da assinatura dos parâmetros do método, se houver um & antes do identificador do parâmetro, então a passagem será por referência.
No Java na verdade é passado uma cópia da referência, por isso que consideram ser passagem por valor. Os parâmetros são variáveis diferentes das passadas por argumento, mas que apontam para a mesma referência.
Exemplo
void executar() {
Objeto a = new Objeto("1"); // a aponta para "1"
Objeto b = new Objeto("2"); // b aponta para "2"
passar(a, b); // passamos a e b ao metodo
}
void passar(Objeto x, Objeto y) { // x e y são duas novas variáveis, mas apontam para a mesma referência que a e b
Objeto tmp = x; // tmp aponta para a mesma referência que x ("1")
x = y; // agora x aponta para a mesma referência que y ("2")
y = tmp; // agora y aponta para a mesma referência que tmp ("1")
// Agora x aponta pra "2" e y pra "1"
// Mas x e y são apenas cópias da referência
// então lá no método executar
// a continua apontando pra "1" e b continua apontando pra "2"
}