Considere o código abaixo:
DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'
DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'
dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'
Então, eu quero copiar o dum
para dumtwo
e alterar dum
sem afetar o dumtwo
. Mas o código acima não está fazendo isso. Quando troco algo dum
, a mesma mudança também está acontecendo dumtwo
.
Acho que, quando digo dumtwo = dum
, Java copia apenas a referência . Então, existe alguma maneira de criar uma nova cópia dum
e atribuí-la dumtwo
?
Básico: cópia de objeto em Java.
Vamos supor uma object-
obj1
, que contém dois objetos, containedObj1 e containedObj2 .cópia superficial: a cópia
superficial cria um novo
instance
da mesma classe e copia todos os campos para a nova instância e o retorna. A classe Object fornece umclone
método e fornece suporte para a cópia superficial.Cópia profunda:
uma cópia profunda ocorre quando um objeto é copiado junto com os objetos aos quais se refere . A imagem abaixo é exibida
obj1
após uma cópia profunda ter sido realizada nela. Não apenasobj1
foi copiado , mas os objetos contidos nele também foram copiados. Podemos usarJava Object Serialization
para fazer uma cópia profunda. Infelizmente, essa abordagem também tem alguns problemas ( exemplos detalhados ).Possíveis problemas:
clone
é difícil de implementar corretamente.É melhor usar cópias defensivas , construtores de cópias (como resposta do @egaga) ou métodos estáticos de fábrica .
clone()
método público , mas não sabe o tipo do objeto no momento da compilação, então você tem um problema. Java tem uma interface chamadaCloneable
. Na prática, devemos implementar essa interface se quisermos criar um objetoCloneable
.Object.clone
está protegido , então devemos substituí- lo por um método público para que ele seja acessível.clone()
método de todas as variáveis de objeto membro também faça cópias profundas, isso é muito arriscado. Você deve controlar o código em todas as classes.Por exemplo, org.apache.commons.lang.SerializationUtils terá um método para o clone Profundo usando serialização ( Origem ). Se precisarmos clonar o Bean, existem alguns métodos de utilitário em org.apache.commons.beanutils ( Origem ).
cloneBean
Clonará um bean com base nos getters e setters de propriedades disponíveis, mesmo que a própria classe de bean não implemente Cloneable.copyProperties
Copiará os valores da propriedade do bean de origem para o bean de destino em todos os casos em que os nomes das propriedades sejam os mesmos.fonte
No pacote
import org.apache.commons.lang.SerializationUtils;
existe um método:Exemplo:
fonte
Serializable
Basta seguir como abaixo:
e onde você quiser obter outro objeto, faça uma clonagem simples. por exemplo:
fonte
Por que não há resposta para o uso da API de reflexão?
É realmente simples.
EDIT: Incluir objeto filho via recursão
fonte
Class A { B child; } Class B{ A parent; }
class car { car car = new car(); }
Eu uso a biblioteca JSON do Google para serializá-la e, em seguida, criar uma nova instância do objeto serializado. Ele faz cópias profundas com algumas restrições:
não pode haver referências recursivas
não copiará matrizes de tipos diferentes
matrizes e listas devem ser digitadas ou não encontrarão a classe para instanciar
pode ser necessário encapsular seqüências de caracteres em uma classe que você se declara
Eu também uso essa classe para salvar preferências do usuário, janelas e outros itens a serem recarregados em tempo de execução. É muito fácil de usar e eficaz.
fonte
Sim, você está apenas fazendo uma referência ao objeto. Você pode clonar o objeto se ele for implementado
Cloneable
.Confira este artigo da wiki sobre cópia de objetos.
Consulte aqui: Cópia de objeto
fonte
Adicione
Cloneable
e abaixo do código à sua turmaUsa isto
clonedObject = (YourClass) yourClassObject.clone();
fonte
Sim. Você precisa copiar profundamente seu objeto.
fonte
Isso também funciona. Assumindo modelo
Primeiro, adicione
compile 'com.google.code.gson:gson:2.8.1'
ao seu aplicativo> classificação e sincronização. EntãoVocê pode excluir o uso de um campo usando a
transient
palavra-chave após o modificador de acesso.Nota: Esta é uma prática ruim. Também não recomendamos o uso
Cloneable
ouJavaSerialization
está lento e quebrado. Escreva um construtor de cópias para obter o melhor desempenho ref .Algo como
Estatísticas de teste da iteração 90000:
Linha
UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);
leva 808msA linha
UserAccount clone = new UserAccount(aO);
leva menos de 1 msConclusão: use gson se seu chefe estiver louco e você preferir velocidade. Use o construtor de segunda cópia, se preferir qualidade.
Você também pode usar o plug-in do gerador de código do construtor de cópia no Android Studio.
fonte
Aqui está uma explicação decente sobre
clone()
se você acaba precisando ...Aqui: clone (método Java)
fonte
Use um utilitário de clonagem profunda:
Isso irá copiar profundamente qualquer objeto java, confira em https://github.com/kostaskougios/cloning
fonte
A Deep Cloning é sua resposta, que requer a implementação da
Cloneable
interface e a substituição doclone()
método.Você vai chamar assim
DummyBean dumtwo = dum.clone();
fonte
dummy
, UmString
, é imutável, você não precisa copiá-loPara fazer isso, você precisa clonar o objeto de alguma forma. Embora o Java tenha um mecanismo de clonagem, não o use se não for necessário. Crie um método de cópia que a cópia funcione para você e faça:
Aqui estão mais alguns conselhos sobre diferentes técnicas para realizar uma cópia.
fonte
Além de copiar explicitamente, outra abordagem é tornar o objeto imutável (nenhum
set
ou outro método de mutação). Dessa maneira, a questão nunca surge. A imutabilidade se torna mais difícil com objetos maiores, mas o outro lado disso é que ele o leva na direção da divisão em objetos pequenos e compostos coerentes.fonte
Alternativa ao método construtor de cópia do egaga . Você provavelmente já possui um POJO; portanto, basta adicionar outro método
copy()
que retorne uma cópia do objeto inicializado.Se você já possui
DummyBean
e deseja uma cópia:Mas ambos funcionam bem, em última análise, cabe a você ...
fonte
fonte
Você pode copiar em profundidade automaticamente automaticamente com o XStream, em http://x-stream.github.io/ :
Adicione-o ao seu projeto (se estiver usando o maven)
Então
Com isso, você tem uma cópia sem a necessidade de implementar nenhuma interface de clonagem.
fonte
java.beans.XMLEncoder
API Java padrão que serializa para XML (embora não exatamente para fins de cópia em profundidade).e no seu código:
fonte
Passe o objeto que você deseja copiar e obtenha o objeto que deseja:
Agora analise o
objDest
objeto desejado.Feliz codificação!
fonte
Você pode tentar implementar
Cloneable
e usar oclone()
método; no entanto, se você usar o método clone, sempre deverá substituirObject
opublic Object clone()
método SEMPRE por padrão .fonte
Se você pode adicionar uma anotação ao arquivo de origem, um processador de anotação ou gerador de código como este pode ser usado.
Uma classe
DummyBeanBuilders
será gerada, que possui um método estáticodummyBeanUpdater
para criar cópias rasas, da mesma maneira que você faria manualmente.fonte
Use
gson
para duplicar um objeto.Suponha que eu tenha um objeto
person
.fonte