Classes, objects and constructors
A class defines state (fields) and behaviour (methods). An object is an instance of a class, created with new.
A constructor runs when the object is created and has no return type. If you write no constructor, Java adds a no-argument default one. Constructors can call each other with this(...).
this refers to the current object. static fields are shared by every instance of the class.
Since Java 25, flexible constructor bodies let you run validation statements before calling super(...) or this(...).
Classes and objects
A class is a blueprint; an object is one thing built from it. new creates the object on the heap and returns a reference to it. Several variables can point at the same object.
Car a = new Car("Nexon");
Car b = a; // same object, two references
b.rename("Harrier");
System.out.println(a.name()); // HarrierFields and methods: state and behaviour
Fields hold an object's state; methods define its behaviour and usually read or change that state. Keep fields private and expose meaningful methods (deposit, withdraw) rather than raw setters.
public class Account {
private long balancePaise;
public void deposit(long paise) {
if (paise <= 0) throw new IllegalArgumentException("amount must be positive");
balancePaise += paise;
}
public long balance() { return balancePaise; }
}Constructors and constructor chaining
A constructor has the class name and no return type. If you write none, Java adds a no-argument one. Overload constructors for different ways to create an object, and chain them with this(...) so the logic lives in one place.
public class Course {
private final String title;
private final int priceInr;
public Course(String title) {
this(title, 0); // free by default
}
public Course(String title, int priceInr) {
if (title == null || title.isBlank()) throw new IllegalArgumentException("title required");
this.title = title;
this.priceInr = priceInr;
}
}The this keyword
this is the current object. Use it to tell a field apart from a parameter with the same name, to pass the current object to another method, or to call another constructor (this(...)).
Initialisation order
When an object is created: static fields and static blocks run once when the class first loads; then, for each object, field initialisers and instance blocks run in order, then the constructor body. With inheritance, the parent's part is built first.
class Demo {
static { System.out.println("1. class loaded (once)"); }
private int x = log("2. field initialiser");
{ System.out.println("3. instance block"); }
Demo() { System.out.println("4. constructor"); }
static int log(String s) { System.out.println(s); return 0; }
}Encapsulation, getters and setters
Hide fields (private) and control access through methods, so you can validate input and change the internals later without breaking callers. Don't add a setter for everything; many fields should be set once, in the constructor. For plain data carriers, use a record.
Static members vs instance members
Static fields are shared by all objects of the class (a counter, a constant); instance fields belong to each object. See the lesson on static and final for the details and pitfalls.
Example
public class Account {
private final String owner;
private double balance;
private static int count = 0; // shared by all accounts
public Account(String owner) {
this(owner, 0); // constructor chaining
}
public Account(String owner, double opening) {
if (opening < 0) throw new IllegalArgumentException("Negative opening balance");
this.owner = owner;
this.balance = opening;
count++;
}
public void deposit(double amount) { balance += amount; }
public double getBalance() { return balance; }
}
Account acc = new Account("Meera", 500);
acc.deposit(250);Common mistake
Adding a constructor with parameters removes the automatic no-arg constructor. Frameworks like JPA and Jackson often need one, so add it back (it can be protected).
Under the hood
new allocates memory (usually from a thread-local allocation buffer, which is very cheap), zeroes the fields, runs field initializers and then the constructor chain from Object downwards. If the JIT proves an object never escapes a method, it may skip the heap allocation entirely (escape analysis).
Check yourself
You declare only Account(String owner). What happens to new Account()?
How this connects
Know these first
Where this leads
- static, final and constants
- Packages, imports and project structure
- Encapsulation, inheritance and polymorphism
- Nested, inner and anonymous classes
- Enums in depth
- Records, enums and sealed types
- Exception handling
- Collections framework: choosing the right one
- java.time: dates done right
- Linked lists, stacks and queues
- Clean code: naming, methods and refactoring
- JVM memory and garbage collection
Part of Java from zero.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.