四種創建對象的方法
一, new
二, clone()
三, 對象序列化
四, reflect
package com.nemo.clone; import java.io.Serializable; public class Clerk implements Serializable{ 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; } }
package com.nemo.clone; import java.io.Serializable; public class Company implements Serializable,Cloneable{ private String name; private Clerk clerk; public Company(String name,Clerk clerk) { this.name = name; this.clerk = clerk; } public Company() { } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } public void dynamicParameter(String ...strings ) { for(String x : strings) { System.out.println(x); } } public String getName() { return name; } public void setName(String name) { this.name = name; } public Clerk getClerk() { return clerk; } public void setClerk(Clerk clerk) { this.clerk = clerk; } }
第二種在"深拷貝和淺拷貝"已經實現過了。
第三種對象序列化
public static void createObjectBySerializable() throws IOException, ClassNotFoundException { Clerk clerk = new Clerk(); clerk.setId(123); clerk.setName("xxx"); Company company = new Company(); company.setName("nmt"); company.setClerk(clerk); OutputStream fileOutputStream = new FileOutputStream("bak.tmp"); ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream); outputStream.writeObject(company); InputStream fileInputStream = new FileInputStream("bak.tmp"); ObjectInputStream inputStream = new ObjectInputStream(fileInputStream); Company scompany = (Company) inputStream.readObject(); System.out.println(company); System.out.println(company.getClerk()); company.setName("company one"); company.getClerk().setId(888); company.getClerk().setName("xxx"); System.out.println(scompany); System.out.println(scompany.getClerk()); scompany.getClerk().setId(999); scompany.getClerk().setName("yyy"); scompany.setName("company two"); System.out.println(company.getName()); System.out.println(company.getClerk().getId()); System.out.println(company.getClerk().getName()); System.out.println("----------------------------"); System.out.println(scompany.getName()); System.out.println(scompany.getClerk().getId()); System.out.println(scompany.getClerk().getName()); }
com.nemo.clone.Company@173a10f com.nemo.clone.Clerk@530daa com.nemo.clone.Company@de6f34 com.nemo.clone.Clerk@156ee8e company one 888 xxx ---------------------------- company two 999 yyy
注意點 : 被創建的對象必須要實現Serializable接口
這種方式的創建對象和深拷貝的結果是一樣的。 對象內的引用類型也會復制一份而不是共享。
第四種 reflect
public static void createObjectByReflect() throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { Class clazz = Company.class; Constructor con = clazz .getConstructor(String.class,Clerk.class); Company company = (Company) con.newInstance("xxx",new Clerk()); Method method = clazz.getMethod("dynamicParameter",(new String[]{}.getClass())); method.invoke(company, (Object)new String[]{"xxx"}); System.out.println(company); System.out.println(company.getName()); }
使用class對象獲取此類的構造器,然后使用構造器的newInstance()方法創建一個對象。
(遇到一個問題,這里在使用反射調用變長參數的方法時,入參會有點不同。
method.invoke(company, (Object)new String[]{"xxx"}); 必須使用(Object)強制轉換。 如果直接用String[]則會報錯。)