【Java基础】Java对象创建的几种方式

举报
No8g攻城狮 发表于 2023/02/18 22:09:59 2023/02/18
【摘要】 Java创建实例对象是不是必须要通过构造函数?这其实是衍生出来的一个面试题。 上面问题的答案很明显了:Java创建实例对象,并不一定必须要调用构造器的。

先上关键内容,所用到的代码请参考文末示例代码。

一、使用new关键字创建对象

这是一种最常用的创建对象的方式。

Student student1 = new Student();

二、使用Class的newInstance()方法创建对象

需要有一个无参构造方法,这个newInstance()方法调用无参的构造函数创建对象。
类名.calss.newInstance( )

Student student2 = Student.class.newInstance();

该方法就是反射机制,事实上Class的newInstance()方法内部就是调用Constructor的newInstance()方法。
Class类的newInstance只能触发无参构造方法创建对象,而构造器类的newInstance能触发有参数或者任意参数的构造方法来创建对象。

三、使用Constructor类的newInstance()方法创建对象

java.lang.reflect.Constructor类里也有一个newInstance()方法可以创建对象。我们可以通过这个newInstance()方法调用有参数的和私有的构造函数。

Constructor student3 = Constructor.class.newInstance();

四、使用克隆clone()方法创建对象

Tips:要使用clone()方法,我们需要先实现Cloneable接口并实现其定义的clone()方法
无论何时我们调用一个对象的clone()方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone()方法创建对象并不会调用任何构造函数。

Student student4 = new Student().clone();

五、使用反序列化创建对象

Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程;
使用反序列化:当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。
在反序列化时,jvm创建对象并不会调用任何构造函数。
为了反序列化一个对象,我们需要让我们的类实现Serializable接口。

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME));
// 5、使用反序列化创建对象
Object student5 = ois.readObject();

六、创建对象的5种方式调用构造器总结

Java创建实例对象是不是必须要通过构造函数?这其实是衍生出来的一个面试题。
上面问题的答案很明显了:Java创建实例对象,并不一定必须要调用构造器的。

七、示例代码(全)

以下是本文所用到的所有示例代码。

7.1 编写Student学生类

package com.effective.chapter2.other;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Cloneable, Serializable {
    private String name;
    private Integer age;

    @Override
    public Student clone() {
        try {
            Student clone = (Student) super.clone();
            // TODO: copy mutable state here, so the clone can't change the internals of the original
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

7.2 编写测试类

package com.effective.chapter2.other;

import java.io.*;
import java.lang.reflect.Constructor;

public class CreateObjectTest {

    private static final String FILE_NAME = "student.obj";

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, IOException {

        // 1、使用new关键字创建对象
        Student student1 = new Student();
        System.out.println("使用new关键字创建对象:" + student1);

        // 2、使用Class类的newInstance()方法创建对象
        Student student2 = Student.class.newInstance();
        System.out.println("使用Class类的newInstance()方法创建对象:" + student2);

        // 3、使用Constructor类的newInstance()方法创建对象
        Constructor student3 = Constructor.class.newInstance();
        System.out.println("使用Constructor类的newInstance()方法创建对象:" + student3);

        // 4、使用clone()方法创建对象
        Student student4 = new Student().clone();
        System.out.println("使用clone()方法创建对象:" + student4);

        try {
            // Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程;
            // 序列化对象
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
            oos.writeObject(student1);

            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME));
            // 5、使用反序列化创建对象
            Object student5 = ois.readObject();
            System.out.println("使用反序列化创建对象:" + student5);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

本文首发于CSDN,为博主原创文章,如果需要转载,请注明出处,谢谢!

完结!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。