Classes and Objects — Constructors, this, Instance vs Static, and Initialization Blocks
In this tutorial, you will learn about Classes and Objects. We cover key concepts, practical examples, and best practices to help you master this topic.
Java classes are blueprints for objects, encapsulating state and behavior through fields, methods, constructors, and initialization blocks. Understanding how objects are constructed and initialized is fundamental to mastering Java — every concept from dependency injection to garbage collection builds on the class-object relationship.
What You'll Learn
- Defining classes with fields, constructors, and methods
- The
thiskeyword and constructor chaining - Instance vs static members
- Instance initializers and static initializers
Why It Matters
Constructors control how objects come into existence. Misunderstanding initialization order leads to bugs where fields are used before they are set. Static vs instance confusion causes memory leaks and design problems.
Real-World Use
Spring creates beans using reflection-based construction, ORMs reconstruct objects from database rows, and every new call invokes a constructor. A REST controller, a JPA entity, and a configuration class are all Java classes.
Defining a Class
A class consists of fields (state), constructors (creation), and methods (behavior):
public class Person {
String name;
int age;
void sayHello() {
System.out.println("Hello, my name is " + name);
}
}
Creating and using an object:
Person person = new Person();
person.name = "Alice";
person.age = 30;
person.sayHello(); // Hello, my name is Alice
Constructors
A constructor has the same name as the class and no return type:
public class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Person p = new Person("Alice", 30);
Default Constructor
If you define no constructors, the compiler generates a no-argument constructor:
public class Person {
String name;
int age;
// default constructor: Person() {}
}
If you define any constructor, the default constructor is not generated:
public class Person {
String name;
Person(String name) {
this.name = name;
}
}
Person p = new Person(); // COMPILE ERROR: no default constructor
Constructor Overloading
Like methods, constructors can be overloaded:
public Person() {
this.name = "Unknown";
this.age = 0;
}
public Person(String name) {
this.name = name;
this.age = 0;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
Constructor Chaining with this()
One constructor can call another using this():
public Person() {
this("Unknown", 0); // calls Person(String, int)
}
public Person(String name) {
this(name, 0); // calls Person(String, int)
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
The this() call must be the first statement in the constructor.
The this Keyword
this refers to the current object instance:
public void setName(String name) {
this.name = name; // distinguishes field from parameter
}
this is also used to pass the current object to another method:
public void printInfo() {
printDetails(this); // passes current object
}
Instance vs Static Members
Instance Members
Belong to each object instance. Each object has its own copy:
public class Person {
String name; // instance field
int age; // instance field
void sayHello() { // instance method
System.out.println("Hello, I'm " + name);
}
}
Static Members
Belong to the class itself, shared across all instances:
public class Person {
static int population; // static field — shared counter
String name;
Person(String name) {
this.name = name;
population++;
}
static void showPopulation() { // static method
System.out.println("Population: " + population);
}
}
Person p1 = new Person("Alice");
Person p2 = new Person("Bob");
Person.showPopulation(); // Population: 2
Static Methods Cannot Access Instance Members
static void badMethod() {
System.out.println(name); // COMPILE ERROR: cannot access instance field
sayHello(); // COMPILE ERROR: cannot access instance method
}
Static methods can only access other static members or work with instances passed as parameters.
Initialization Blocks
Instance Initializer
Runs before the constructor body, every time an object is created:
public class Person {
String name;
int id;
// instance initializer
{
id = nextId++; // common initialization logic
}
Person(String name) {
this.name = name;
}
}
Static Initializer
Runs once when the class is first loaded:
public class Person {
static int nextId;
static List<String> validNames;
static {
nextId = 1000;
validNames = new ArrayList<>();
validNames.add("Alice");
validNames.add("Bob");
System.out.println("Static init block executed");
}
}
Initialization Order
When you create an object, things happen in this exact order:
- Static initializers (once per class load)
- Instance initializers
- Constructor body
public class Demo {
static { System.out.print("1 "); }
{ System.out.print("2 "); }
Demo() { System.out.print("3 "); }
}
new Demo(); // prints "2 3" (static already ran if first use)
new Demo(); // prints "2 3" (static does not run again)
Common Mistakes
- Calling instance methods from static context. A static method cannot access
thisor instance fields without an explicit object reference. - Forgetting to call
super()in a constructor. The compiler adds it automatically if not present, but if the parent class has no no-arg constructor, you must callsuper(...)explicitly. - Accidentally shadowing fields.
name = namein a constructor assigns the parameter to itself, not the field. Usethis.name = name. - Making everything static. Static fields are shared globally, making testing and concurrency difficult. Prefer instance fields for state.
- Using instance initializers when constructors suffice. Instance initializers are useful for anonymous classes or when sharing logic across constructors, but constructors are more explicit.
Practice Questions
1. What is the difference between a static field and an instance field?
An instance field has a separate copy per object. A static field has one copy shared across all instances.
2. When does a static initializer block run?
It runs once when the class is first loaded by the JVM.
3. What happens if a constructor does not call this() or super()?
The compiler inserts super() (the no-arg constructor of the parent class) as the first statement.
4. Can a constructor be private?
Yes. A private constructor prevents external instantiation — used in Singleton Patternton" >}} pattern, utility classes, and Factory methods.
5. What is constructor chaining?
Calling one constructor from another using this(...). It reduces code duplication by reusing constructor logic.
Challenge Question:
Design a BankAccount class with instance fields accountNumber (auto-generated), balance, and ownerName. Use a static field to track the next account number and a static initializer to set the starting value. Include overloaded constructors: one with just a name (balance = 0), and one with name and initial balance. Print the account number on creation.
FAQ
Mini Project
Write a program ClassDesign.java that:
- Defines a
Bookclass with private instance fields (title, author, isbn, year) and a static fieldtotalBooks - Provides overloaded constructors (title only, title+author, all fields) using
this()chaining - Uses an instance initializer to increment
totalBooks - Adds a static method
getTotalBooks()and an instance methoddisplayInfo() - Creates 5
Bookobjects with different constructors and displays their info - Shows the total book count after creation
What's Next
Classes store data, but how do you control access to that data? Lesson 12 explores encapsulation — access modifiers, getters and setters, the JavaBeans naming convention, and the principle of data hiding that protects your objects from invalid state.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro