What happens when a Java object is created?

As a software developer how many times we create an object in Java, almost for everything there is an object of a class to do the given task. But do you know what all happens behind the scene when we create an object?

In this post, we will discuss several things that happen in an order to ensure the object is constructed properly.

Introduction

Java object

Before creating a Java object, the class byte code (.class file) must be loaded from the file system to memory. Locating the byte code for a given class name and converting that code into a Java class instance is known as class loading. There is one class created for each type of Java class.

Objects in Java are created on heap memory. An object is created based on its class. A class is a template that defines states and behavior defines how an object is created.

When a Java object is created following steps will happen one by one –

    • JVM allocates 8 bytes of memory for the reference variable & assigns a default value as null.
    • JVM will verify whether class loading is done or not, if the class is already loaded then it will ignore or else it will perform class loading.
    • At the time of class loading, if any static variable is there then memory will be allocated for them.
    • At the time of class loading, if it contains any String literals a new String object will be created to represent that literal. This may not happen if the same String is previously been interned.
    • By using the new operator, object memory will be created inside heap memory.
    • At the time of object creation, if any instance variables are there then those will allocate memory inside object Memory.
    • It will assign object memory address to the reference variable which is created first.
    • If there is not sufficient space available to allocate memory for the object, then the creation of the class instance abrupt with an OutOfMemoryError. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values.

When an object is created, memory is allocated to hold the object properties. An object reference pointing to that memory location is also created. To use the object in the future, that object reference must be stored as a local variable or as an object member variable.

There is no limit on how many objects from the same class can be created. Code and static variables are stored only once, no matter how many objects are created. Memory is allocated for the object member variables when the object is created. Thus, the size of an object is determined not by its code’s size but by the memory it needs for its member variables to be stored.

We have discussed what happens when a Java object is created, let’s check the ways to create an object in Java.  Following are some ways in which you can create objects in Java –

Creating an object with the new keyword

In most cases, the new objects are created using the new keyword. This is the most basic way to create an object by calling a constructor (default or parameterized constructor). In the below example, we create an object of AppTest when the program starts running.

public class AppTest{
    public static void main(String[] args) {
        AppTest test = new AppTest();
    }
}

Creating an object with the newInstance()

If the name of the class is known & it has a public default constructor we can create an object using – Class.forName. We can use it to create the Object of a Class. Class.forName actually loads the Class in Java but doesn’t create any Object. To create an Object of the Class you have to use the new Instance Method of the Class.

public class AppTest{

    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("com.coddersdesks.AppTest");
            AppTest test =  (AppTest) clazz.newInstance();
            test.print("hello this is a test with newInstance()");
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public void print(String message){
        System.out.println("message "+message);
    }
}
message hello this is a test with newInstance()

Creating an object using the clone() method

Whenever we call the clone() method on any java object, the JVM creates a new object and copies all content of the old object into it, read more about shallow copy vs deep copy. Creating an object using the clone method does not invoke any constructor. To use the clone() method on an object we need to implement Cloneable and define the clone() method in it.

Cloning is not automatic, there is some help though, as all Java objects inherit the protected Object clone() method from the Object class. This base method would allocate the memory and do the bit by bit copying of the object’s states.

public class Student implements Cloneable{

	 int rollno;
	
	 String name;
	
	 Course course;

	public Student(int rollno, String name, Course course) {
		super();
		this.rollno = rollno;
		this.name = name;
		this.course = course;
	}

	@Override
	public String toString() {
		return "Student [rollno=" + rollno + ", name=" + name + ", course=" + course + "]";
	}
	
	protected Object clone() throws CloneNotSupportedException{
		return super.clone();
	}
}
  1. Here we are creating the clone from an existing Object and not any new Object.
  2. To support the cloning Class need to implement Cloneable Interface otherwise it will throw CloneNotSupportedException.

The clone() method copies the whole object’s memory in one operation and this is much faster than using the new keyword and copying each variable so if you need to create lots of objects with the same type, performance will be better if you create one object and clone new ones from it.

Re-creating an object using deserialization

I hope you are aware of serialization and deserialization in Java. If you want to recall it you can read Serialization in Java using Serializable Interface. Do you know there is another way as well? Serialization with Java Externalizable Interface.

So, whenever there is a need to manage the object states (properties), we can use serialization. The term Object Serialization refers to the act of converting the object to a byte stream. The common uses of serialization are sending an object over the network, persisting the object into the database using ORM such as hibernate or writing the object to the file system.

serialization in Java

During deserialization, the object can be re-created from that stream of bytes. The only requirement is that the same class has to be available both times when the object is serialized and also when the object is re-created. If that happens on different application servers, then the same class must be available on both servers. The same class means that the same version of the class must be available, otherwise, the object won’t be able to be re-created.

When a class is modified, there could be a problem re-creating those objects that were serialized using an earlier version of the class.

Creating Object using newInstance() method of Constructor

The newInstance() method of java.lang.reflect.Constructor is similar to newInstance() of Class, which can be used to create objects. Using this we can call the parameterized constructor and private constructor as well.

Both newInstance() methods are known as reflective ways to create objects. In fact newInstance() method of Class internally uses newInstance() method of Constructor class. Refer to the below code snippet for detail.

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class AppTest{

    private String testName;

    public AppTest(){

    }

    public AppTest(String testName){
        this.testName = testName;
    }

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

        Constructor<AppTest> constructor = AppTest.class.getDeclaredConstructor(); // default constructor
        AppTest test = constructor.newInstance();
        Constructor<AppTest> constructor1 = AppTest.class.getDeclaredConstructor(String.class); // parameterized constructor

        test.print("called using constructor newInstance() and default constructor");
        AppTest test1 = constructor1.newInstance("test name passed to constructor");
        test1.print("called using constructor newInstance() and parameterized constructor");
    }

    public void print(String message){
        System.out.println("message "+message);
        if(this.testName != null){
            System.out.println(this.testName);
        }
    }
}

When you run the above code it will print the following.

message called using constructor newInstance() and default constructor
message called using constructor newInstance() and parameterized constructor
test name passed to the constructor

Here we have discussed what happened behind the scene when we create a new Java object and various ways to create an object.

Happy Learning !!

Leave a Comment