Detailed Explanation of Java Object Creation and Initialization Process
This article provides an in‑depth overview of how Java objects are created and initialized, covering class loading, the various ways to instantiate objects (new, reflection, clone, deserialization), the step‑by‑step memory allocation and field initialization sequence, and the order of static and instance initialization across inheritance hierarchies.
In Java, an object must be properly initialized before it can be used; the JVM checks whether the class is loaded and initialized, performing class loading and invoking the class initializer if necessary.
Object creation can be triggered by various mechanisms: the new operator, reflection via Class.forName("Student").newInstance() or Constructor<Student>.newInstance() , the clone() method, and deserialization. Each method ultimately results in an invokevirtual instruction that allocates the object.
The initialization process consists of memory allocation, default‑value assignment, instance‑variable initialization, instance‑initializer blocks, and constructor execution. Instance‑variable initializers and instance‑initializer blocks are compiled into the constructor and run after the super‑class constructor call.
Class initialization occurs during the loading phase: static variables are allocated and given default values, then the <clinit> method runs, executing static initializers in the order they appear. The superclass <clinit> runs before the subclass <clinit> , guaranteeing that static state is ready before subclass code executes.
Examples illustrate the order of execution for parent and child classes, showing how overridden methods can see default field values during super‑class construction, and how multiple initializations affect the final state of an object. A full sample program demonstrates creation via new , reflection, Constructor , clone , and deserialization, and prints the resulting object states.
public class Student implements Cloneable, Serializable {
private int id;
public Student() {}
public Student(Integer id) { this.id = id; }
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
public static void main(String[] args) throws Exception {
// new
Student s1 = new Student(123);
// reflection (Class)
Student s2 = (Student) Class.forName("Student").newInstance();
// reflection (Constructor)
Constructor<Student> ctor = Student.class.getConstructor(Integer.class);
Student s3 = ctor.newInstance(123);
// clone
Student s4 = (Student) s3.clone();
// serialization
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student.bin"));
out.writeObject(s4); out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("student.bin"));
Student s5 = (Student) in.readObject();
System.out.println(s5);
}
}Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.