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[]则会报错。)