Java中五种新建对象方式

本文介绍了Java中创建对象的五种方法,包括使用new关键字、newInstance方法、构造函数类的newInstance方法、clone方法及反序列化,并探讨了this与super关键字的区别及其用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】创建对象的5种方式

① 使用new关键字

这是最常见的创建对象的方法,并且也非常简单。通过使用这种方法我们可以调用任何我们需要调用的构造函数。

Employee emp1 = new Employee();

② 使用class类的newInstance方法

我们也可以使用class类的newInstance()方法来创建对象。

此newInstance()方法调用无参构造函数以创建对象。

我们可以通过newInstance() 用以下方式创建对象:

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();

//或者

Employee emp2 = Employee.class.newInstance();


③ 使用构造函数类的 newInstance方法

与使用class类的newInstance()方法相似,java.lang.reflect.Constructor类中有一个可以用来创建对象的newInstance()函数方法。

通过使用这个newInstance()方法我们也可以调用参数化构造函数和私有构造函数。

Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();

这些 newInstance() 方法被认为是创建对象的反射手段。

实际上,内部类的newInstance()方法使用构造函数类的 newInstance() 方法。

这就是为什么后者是首选并且使用不同的框架如Spring, Hibernate, Struts等。


④ 使用clone方法

实际上无论何时我们调用clone() 方法,Java虚拟机都为我们创建了一个新的对象并且复制了之前对象的内容到这个新的对象中。

使用 clone()方法创建对象不会调用任何构造函数。

为了在对象中使用clone()方法,我们需要在其中实现可克隆类型并定义clone()方法。

Employee emp4 = (Employee) emp3.clone();


⑤ 使用反序列化

无论何时我们对一个对象进行序列化和反序列化,Java虚拟机都会为我们创建一个单独的对象。在反序列化中,Java虚拟机不会使用任何构造函数来创建对象。

对一个对象进行序列化需要我们在类中实现可序列化的接口。

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();

正如我们在以上的字节代码片段中所看到的,除第一种被转换为一个新的函数和一个 invokespecial 指令以外,其它4种方法都被调用并转换为invoke virtual。


⑥ 代码示例

让我们来看看准备创建对象的 Employee 类:

class Employee implements Cloneable, Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    public Employee() {
        System.out.println("Employee Constructor Called...");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Employee [name=" + name + "]";
    }
    @Override
    public Object clone() {
        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}


在下面的Java程序中我们用5种方式来创建 Employee对象。


public class ObjectCreation {
    public static void main(String... args) throws Exception {
        // By using new keyword
        Employee emp1 = new Employee();
        emp1.setName("Naresh");
        System.out.println(emp1 + ", hashcode : " + emp1.hashCode());
        // By using Class class's newInstance() method
        Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                               .newInstance();
        // Or we can simply do this
        // Employee emp2 = Employee.class.newInstance();
        emp2.setName("Rishi");
        System.out.println(emp2 + ", hashcode : " + emp2.hashCode());
        // By using Constructor class's newInstance() method
        Constructor<Employee> constructor = Employee.class.getConstructor();
        Employee emp3 = constructor.newInstance();
        emp3.setName("Yogesh");
        System.out.println(emp3 + ", hashcode : " + emp3.hashCode());
        // By using clone() method
        Employee emp4 = (Employee) emp3.clone();
        emp4.setName("Atul");
        System.out.println(emp4 + ", hashcode : " + emp4.hashCode());
        // By using Deserialization
        // Serialization
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));
        out.writeObject(emp4);
        out.close();
        //Deserialization
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
        Employee emp5 = (Employee) in.readObject();
        in.close();
        emp5.setName("Akash");
        System.out.println(emp5 + ", hashcode : " + emp5.hashCode());
    }
}

此程序输出结果如下:


Employee Constructor Called...
Employee [name=Naresh], hashcode : -1968815046
Employee Constructor Called...
Employee [name=Rishi], hashcode : 78970652
Employee Constructor Called...
Employee [name=Yogesh], hashcode : -1641292792
Employee [name=Atul], hashcode : 2051657
Employee [name=Akash], hashcode : 63313419

【2】this与super

① this关键字的用法

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指
针。
this的用法在java中大体可以分为3种:

  • 普通的直接引用,this相当于是指向当前对象本身。
  • 形参与成员名字重名,用this来区分:
  • 引用本类的构造函数

② super关键字的用法

super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离
自己最近的一个父类。

super也有三种用法:

  • 普通的直接引用
    与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。
  • 子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
  • 引用父类构造函数
    super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
    this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。

this与super的区别

  • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)

  • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)

  • super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。

  • super()和this()均需放在构造方法内第一行。

  • 尽管可以用this调用一个构造器,但却不能调用两个。

  • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

  • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值