面试题之对象创建的五种方式

一、简介

在Java中,创建对象的方式有五种,分别为:

  • 通过new()调用构造方法创建对象;
  • 通过反射xxx.getClass().newInstance()创建对象;
  • 通过反射construct.newInstance()创建对象;
  • 通过xxx.clone()克隆方法创建对象;
  • 通过readObject()反序列化创建对象;

下面通过示例分别说明五种方法。

二、示例

首先创建一个Student学生类,代码如下:

/**
 * 学生类
 */
public class Student implements Serializable {
    /**
     * 学生ID
     */
    private String id;
    /**
     * 学生姓名
     */
    private String name;
    /**
     * 学生年龄
     */
    private Integer age;

    /**
     * 无参构造
     */
    public Student() {
    }

    /**
     * 有参构造
     */
    public Student(String id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

【a】通过new()调用构造方法创建对象

public class TestCreateObject {
    public static void main(String[] args) {
        Student student = createStudent();
        //Student{id='2c3b86f7-82b5-4e6f-a773-d69d7376225c', name='张三', age=20}
        System.out.println(student);
    }

    private static Student createStudent() {
        return new Student(UUID.randomUUID().toString(), "张三", 20);
    }
}

【b】通过反射xxx.getClass().newInstance()创建对象

public class TestCreateObject {
    public static void main(String[] args) {
        Student student = createStudent();
        //Student{id='f33e3130-559b-4a04-959d-15b9e3fa1e91', name='李四', age=30}
        System.out.println(student);
    }

    private static Student createStudent() {
        try {
            Student student = Student.class.newInstance();
            //得到一个空的对象Student{id='null', name='null', age=null}
            System.out.println(student);
            student.setId(UUID.randomUUID().toString());
            student.setName("李四");
            student.setAge(30);
            return student;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

【c】通过反射construct.newInstance()创建对象

public class TestCreateObject {
    public static void main(String[] args) {
        Student student = createStudent();
        //Student{id='3c08ed9c-d95e-4694-af4e-359dfc3a0136', name='王五', age=40}
        System.out.println(student);
    }

    private static Student createStudent() {
        try {
            //获取Student类对应的CLASS字节码对象
            Class<Student> studentClass = Student.class;
            //获取Student类中有参构造方法
            Constructor<Student> constructor = studentClass.getConstructor(String.class, String.class, Integer.class);
            //创建对象
            return constructor.newInstance(UUID.randomUUID().toString(), "王五", 40);
        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}

【d】通过xxx.clone()克隆方法创建对象

Student类中需要重写对象克隆方法clone(),并且实现克隆标记接口Cloneable.

public class Student implements Serializable,Cloneable {
    //.....
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class TestCreateObject {
    public static void main(String[] args) {
        Student student = createStudent();
        //Student{id='3679a150-3ce1-486e-ba5c-6823e6aee020', name='赵六', age=50}
        System.out.println(student);
    }

    private static Student createStudent() {
        Student student1 = new Student(UUID.randomUUID().toString(), "赵六", 50);
        try {
            return (Student) student1.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

【e】通过readObject()反序列化创建对象

public class TestCreateObject {
    public static void main(String[] args) {
        Student student = createStudent();
        //Student{id='76de11c1-300d-489b-903a-7bc27e71c664', name='田七', age=60}
        System.out.println(student);
    }

    private static Student createStudent() {
        Student student = new Student(UUID.randomUUID().toString(), "田七", 60);
        //将student对象序列化到student.txt文件中
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:\\student.txt"));
             ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:\\student.txt"))) {
            oos.writeObject(student);
            //从student.txt文件中反序列化出student对象
            return (Student) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值