Por que o Object.clone () é nativo em Java?

O método clone em Object , que cria uma cópia exata de um object, é declarado como:

 protected native Object clone() throws CloneNotSupportedException; 

Por que é native ?

Basicamente, porque o método clone() faz algo que você não pode fazer na linguagem Java: clona o estado do object, incluindo sua designação de class real.

O mecanismo de clonagem em Java é baseado em cada class que chama o método clone da superclass, até o Object . Object então usa esse método de clone nativo “mágico” para duplicar o object original, incluindo sua class real.

Pense nisso:

 class A implements Cloneable { public A clone() { A obj = (A) super.clone(); // Do some deep-copying of fields return obj; } } class B extends A { public B clone() { B obj = (B) super.clone(); // Do some deep-copying of fields not known to A return obj; } } 

Agora imagine que você tem um object do tipo B e clone nele. Você espera obter um object B , cuja class é reconhecida internamente como B , não como Object . B não sabe a implementação de tudo em A e, portanto, precisa chamar o método clone A Mas se A clone implementado na linguagem Java, em vez de chamar super.clone() , o object que ele retornaria teria que ser A Não pode usar o new B() (suponha que B não era conhecido quando A foi criado).

Poderia fazer algo com reflection, mas como saberia qual construtor chamar para que todos os campos finais fossem preenchidos corretamente?

Então, o truque é que A não o faz sozinho, ele chama super.clone() , e isso vai até o Object , e ele usa um método nativo que faz uma cópia byte a byte do object original. , ajustando para o novo local de heap. Assim, o novo object magicamente se torna um object B e o tipo de conversão não falharia.

Por que não retornar um Object então? Porque isso não seria clonagem. Quando você chama clone espera obter um object tanto do mesmo estado (campos) quanto da mesma class (methods sobrescritos e adicionados). Se ele retornasse um object cuja designação de class interna fosse Object , você só teria access a itens que o Object oferecesse, como toString() , e você não seria capaz de acessar seus campos privados de outro object B ou atribuí-lo para uma variável do tipo B

Veja a documentação do clone:

Caso contrário, esse método cria uma nova instância da class desse object e inicializa todos os seus campos com exatamente o conteúdo dos campos correspondentes desse object, como se fosse por atribuição; o conteúdo dos campos não é clonado.

Essa operação pode ser feita de maneira muito eficiente com código nativo, já que alguma memory precisa ser copiada diretamente. É semelhante em relação a System.arrayсopy , que também é nativo. Para obter detalhes, consulte esta pergunta: É possível encontrar a origem de um método nativo Java?

Note que normalmente você deve evitar Object.clone () e usar, por exemplo, um construtor de cópia, veja Como eu copio um object em Java?

É nativo, porque algumas classs de sistema ‘ Clone() são escritas em C ++ para melhorar o desempenho.

Intereting Posts