JAVA创建对象的几种方式
四种创建对象的方法
一, 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[]则会报错。)