public class Test implements Cloneable { private int no; private String name; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Bu sınıfı kullanarak aşağıdaki gibi bir uygulama ile kopyasını alıyoruz ve özelliklerini değiştiriyoruz :
public class CloneTestApp { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); try { Test t2=(Test)t.clone(); t2.setNo(2); t2.setName("Tester2"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Kopya:"+t2.getNo()+","+t2.getName()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }Uygulamayı çalıştırdığımızda aşağıdaki gibi bir çıktı vermektedir :
Orjinal:1,Tester Kopya:2,Tester2Görüldüğü gibi kopyası alınan nesnede değişiklik yaptığımızda asıl olan nesnede bir değişiklik olmamıştır.
java.lang.CloneNotSupportedException: com.fibiler.clone.Test at java.lang.Object.clone(Native Method) at com.fibiler.clone.Test.clone(Test.java:23) at com.fibiler.clone.CloneTestApp.main(CloneTestApp.java:12)Eğer clone() ile değilde atama yoluyla ikinci bir nesne yaratsaydık örnek aşağıdaki gibi olurdu :
public class CloneTestApp2 { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); Test t2=t; t2.setNo(2); t2.setName("Tester2"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Kopya:"+t2.getNo()+","+t2.getName()); } }Bu uygulamayı çalıştırdığımızda aşağıdaki gibi çıktı üretir :
Orjinal:2,Tester2 Kopya:2,Tester2
public class Test implements Cloneable { private int no; private String name; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Bu test sınıfını içeren bir sınıf yapıyoruz:
public class TestDeep implements Cloneable { private int no; private Test test; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Test getTest() { return test; } public void setTest(Test test) { this.test = test; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Şimdi bir uygulama yapıp TestDeep sınıfını clone() yöntemini çağırıyoruz ve içerisindeki test nesnesini değiştiriyoruz:
public class DeepCloneTestApp { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); TestDeep parent=new TestDeep(); parent.setNo(100); parent.setTest(t); try { TestDeep t2=(TestDeep)parent.clone(); t2.setNo(1283); t2.getTest().setNo(1453); t2.getTest().setName("Deep"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Orjinal Deep:"+t2.getNo()); System.out.println("Kopya Deep:"+t2.getTest().getNo()+"," +t2.getTest().getName()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }Uygulama aşağıdaki çıktıyı verir :
Orjinal:1453,Deep Orjinal Deep:1283 Kopya Deep:1453,DeepDikkat edilir ise aşağıdaki gibi yapılan değişiklikler t nesnesini de değiştirmiştir.
t2.getTest().setNo(1453); t2.getTest().setName("Deep");Bu nedenle t nesnesinin değerleri de 1453 ve Deep olmuştur. Sonuç olarak TestDeep sınıfının nesnesi t2 kopyalandığında içindeki t nesnesi kopyalanmamıştır.
public class Test implements Cloneable { private int no; private String name; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Bu test sınıfını kullanan bir ana sınıfı aşağıdaki gibi yapabiliriz :
public class TestDeep implements Cloneable { private int no; private Test test; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Test getTest() { return test; } public void setTest(Test test) { this.test = test; } @Override protected Object clone() throws CloneNotSupportedException { TestDeep testDeep=(TestDeep)super.clone(); Test testClone=(Test)testDeep.getTest().clone(); testDeep.setTest(testClone); return testDeep; } }clone() yönteminde TestDeep kendisinin kopyaladıktan sonra kendisi içindeki test nesnesini de kopyalayıp set etmektedir. Bu şekilde TestDeep kopyalandığında test nesnesi de kopyalanmış olacaktır. Aşağıdaki gibi bir uygulama yapalım :
public class DeepCloneTester { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); TestDeep parent=new TestDeep(); parent.setNo(100); parent.setTest(t); try { TestDeep t2=(TestDeep)parent.clone(); t2.setNo(1283); t2.getTest().setNo(1453); t2.getTest().setName("Deep"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Orjinal Deep:"+t2.getNo()); System.out.println("Kopya Deep:"+t2.getTest().getNo()+"," +t2.getTest().getName()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }Bu uygulamayı çalıştırdığımızda aşağıdaki gibi bir çıktı üretecektir :
Orjinal:1,Tester Orjinal Deep:1283 Kopya Deep:1453,DeepGörüldüğü gibi t1 içindeki Test tipindeki nesne değiştirlmesine rağmen orjinal nesne değişmemiştir.
t2.getTest().setNo(1453); t2.getTest().setName("Deep");
import java.io.Serializable; public class Test implements Serializable { private int no; private String name; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Bu test sınıfını kullanan bir ana sınıfı aşağıdaki gibi yapabiliriz :
import java.io.Serializable; public class TestDeep implements Serializable { private int no; private Test test; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Test getTest() { return test; } public void setTest(Test test) { this.test = test; } }Aşağıdaki gibi bir uygulama yapalım :
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class DeepCloneTestObjectStream { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); TestDeep parent=new TestDeep(); parent.setNo(100); parent.setTest(t); try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream o = new ObjectOutputStream(bo); o.writeObject(parent); ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream i = new ObjectInputStream(bi); TestDeep t2 = (TestDeep)i.readObject(); t2.setNo(1283); t2.getTest().setNo(1453); t2.getTest().setName("Deep"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Orjinal Deep:"+t2.getNo()); System.out.println("Kopya Deep:"+t2.getTest().getNo()+"," +t2.getTest().getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }Bu uygulamayı çalıştırdığımızda aşağıdaki gibi bir çıktı üretecektir :
Orjinal:1,Tester Orjinal Deep:1283 Kopya Deep:1453,DeepGörüldüğü gibi t nesnesi değiştirilmesine rağmen orjinal nesne değişmemiştir.
t2.getTest().setNo(1453); t2.getTest().setName("Deep");Sonuç olarak bir nesneyi içindeki nesnelerin hepsini en alttaki nesnelere gidecek şekilde içerecek şekilde kopyalamak için serileştirme özelliğ kullanılabilir. Ancak nesnelerin tümü Serializable olmalıdır.
import java.io.Serializable; public class Test implements Serializable { private int no; private String name; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Bu test sınıfını kullanan bir ana sınıfı aşağıdaki gibi yapabiliriz :
import java.io.Serializable; public class TestDeep implements Serializable { private int no; private Test test; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Test getTest() { return test; } public void setTest(Test test) { this.test = test; } }Aşağıdaki gibi bir uygulama yapalım :
import org.apache.commons.lang3.SerializationUtils; public class DeepCloneTestApacheLang { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); TestDeep parent=new TestDeep(); parent.setNo(100); parent.setTest(t); TestDeep t2=(TestDeep)SerializationUtils.clone(parent); t2.setNo(1283); t2.getTest().setNo(1453); t2.getTest().setName("Deep"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Orjinal Deep:"+t2.getNo()); System.out.println("Kopya Deep:"+t2.getTest().getNo()+"," +t2.getTest().getName()); } }Bu uygulamayı çalıştırdığımızda aşağıdaki gibi bir çıktı üretecektir :
Orjinal:1,Tester Orjinal Deep:1283 Kopya Deep:1453,DeepGörüldüğü gibi t nesnesi değiştirilmesine rağmen orjinal nesne değişmemiştir.
t2.getTest().setNo(1453); t2.getTest().setName("Deep");Sonuç olarak bir nesneyi içindeki nesnelerin hepsini en alttaki nesnelere gidecek şekilde içerecek şekilde kopyalamak için SerializationUtils clone() yöntemi kullanılabilir. Ancak nesnelerin tümü Serializable olmalıdır.
public class Test { private int no; private String name; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Bu test sınıfını kullanan bir ana sınıfı aşağıdaki gibi yapabiliriz :
public class TestDeep{ private int no; private Test test; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Test getTest() { return test; } public void setTest(Test test) { this.test = test; } }
import com.google.gson.Gson; public class DeepCloneTestGson { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); TestDeep parent=new TestDeep(); parent.setNo(100); parent.setTest(t); Gson gson = new Gson(); TestDeep t2 = gson.fromJson(gson.toJson(parent), TestDeep.class); t2.setNo(1283); t2.getTest().setNo(1453); t2.getTest().setName("Deep"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Orjinal Deep:"+t2.getNo()); System.out.println("Kopya Deep:"+t2.getTest().getNo()+"," +t2.getTest().getName()); } }Bu uygulamayı çalıştırdığımızda aşağıdaki gibi bir çıktı üretecektir :
Orjinal:1,Tester Orjinal Deep:1283 Kopya Deep:1453,DeepGörüldüğü gibi t nesnesi değiştirilmesine rağmen orjinal nesne değişmemiştir.
t2.getTest().setNo(1453); t2.getTest().setName("Deep");Sonuç olarak bir nesneyi içindeki nesnelerin hepsini en alttaki nesnelere gidecek şekilde içerecek şekilde kopyalamak için Gson kullanılabilir.
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class DeepCloneTestJackson { public static void main(String[] args) { Test t=new Test(); t.setNo(1); t.setName("Tester"); TestDeep parent=new TestDeep(); parent.setNo(100); parent.setTest(t); TestDeep t2=null; try { ObjectMapper objectMapper = new ObjectMapper(); t2 = objectMapper .readValue(objectMapper.writeValueAsString(parent), TestDeep.class); t2.setNo(1283); t2.getTest().setNo(1453); t2.getTest().setName("Deep"); System.out.println("Orjinal:"+t.getNo()+","+t.getName()); System.out.println("Orjinal Deep:"+t2.getNo()); System.out.println("Kopya Deep:"+t2.getTest().getNo()+"," +t2.getTest().getName()); } catch (JsonMappingException e) { e.printStackTrace(); } catch (JsonProcessingException e) { e.printStackTrace(); } } }Jakson'ı Maven ile eklemek için aşağıdaki gibi bağımlılık eklenmesi gerekir:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.13.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.2.2</version> </dependency>