Summary of 5 ways to create objects in Java

  • 2020-06-03 06:34:26
  • OfStack

As Java developers, we create a lot of objects every day, but we usually use dependency management systems like Spring to create objects. However, there are many ways to create objects, as we will learn in this article.

There are five ways to create objects in Java, with examples below and their bytecode

使用new关键字 } → 调用了构造函数
使用Class类的newInstance方法 } → 调用了构造函数
使用Constructor类的newInstance方法 } → 调用了构造函数
使用clone方法 } → 没有调用构造函数
使用反序列化 } → 没有调用构造函数

As Java developers, we create a lot of objects every day, but we usually use dependency management systems like Spring to create objects. However, there are many ways to create objects, as we will learn in this article.

There are five ways to create objects in Java, with examples below and their bytecode

If you run the end of the program, you will find that methods 1,2,3 create objects with constructors, and methods 4,5 do not call constructors.

1. Use the new keyword

This is the most common and easiest way to create an object. In this way, we can call any constructor (parametrically and parametrically).


Employee emp1 = new Employee();
0: new      #19     // class org/programming/mitra/exercises/Employee
3: dup
4: invokespecial #21     // Method org/programming/mitra/exercises/Employee."":()V

2. Use the newInstance method of the Class class

We can also create objects using the newInstance method of the Class class. The newInstance method calls the parameterless constructor to create the object.

We can call the newInstance method to create an object by:


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

Employee emp2 = Employee.class.newInstance();
51: invokevirtual  #70  // Method java/lang/Class.newInstance:()Ljava/lang/Object;

Use the newInstance method of the Constructor class

Like those Class newInstance method of a class, java. lang. reflect. Constructor class also has a newInstance method can create the object. The newInstance method allows you to call both parameterized and private constructors.


Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();
111: invokevirtual #80 // Method java/lang/reflect/Constructor.newInstance:([Ljava/lang/Object;)Ljava/lang/Object;

These two newInstance methods are known as reflections. In fact, the newInstance method of Class calls the newInstance method of Constructor internally. This is why many frameworks such as Spring, Hibernate, Struts, and others use the latter. To see the difference between the two newInstance methods,

4. Use clone method

Whenever we call the clone method on an object, jvm creates a new object and copies the contents of the previous object. Creating an object with the clone method does not call any constructors.

To use the clone method, we need to first implement the Cloneable interface and implement its defined clone method.


Employee emp4 = (Employee) emp3.clone();
162: invokevirtual #87 // Method org/programming/mitra/exercises/Employee.clone ()Ljava/lang/Object;

5. Use deserialization

When we serialize and deserialize an object, jvm creates a separate object for us. When deserializing, jvm creates objects without calling any constructors.

To deserialize an object, we need to have our class implement the Serializable interface


ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();
261: invokevirtual #118  // Method java/io/ObjectInputStream.readObject:()Ljava/lang/Object;

As we can see from the bytecode snippet above, all four methods are converted to invokevirtual(the direct way to create an object), and the first method is converted to two calls, new and invokespecial(constructor calls).

example

Let's take a look at creating objects for the following Employee class:


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;
  }
}

In the following Java program, we will create Employee objects in five ways.


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());
  }
}

The program will output:


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

Related articles: