Classes & Objects
Classes and objects are the foundation of object-oriented programming in Java. A class is a blueprint that defines the structure and behavior of a type; an object is a concrete instance of that blueprint living on the heap. Everything you build in Java—from a tiny value holder to a sprawling service—ultimately resolves to classes and the objects you create from them.
Defining a Class
A class groups state (fields) and behavior (methods) under a single name. By convention class names use PascalCase.
public class Account {
// Fields (instance state)
private String owner;
private long balanceCents;
// Method (behavior)
public void deposit(long cents) {
this.balanceCents += cents;
}
public long getBalanceCents() {
return balanceCents;
}
}
Each field declared without static belongs to every instance independently. Methods operate on that per-instance state.
Fields and Methods
Fields hold an object’s data. Methods read and mutate that data, exposing a controlled surface to the outside world. A field’s default value depends on its type: reference types default to null, numerics to 0, boolean to false. Local variables, by contrast, have no default and must be assigned before use.
Note: Prefer giving fields explicit initializers or assigning them in a constructor. Relying on defaults silently hides bugs.
Creating Objects: the new Keyword
The new operator allocates memory on the heap, runs the constructor, and returns a reference.
Account a = new Account();
a.deposit(5_000);
System.out.println(a.getBalanceCents());
Output:
5000
The variable a does not contain the object—it holds a reference to it. Assigning Account b = a; copies the reference, so a and b point at the same object.
The Object Lifecycle
A Java object passes through three phases:
- Creation —
newallocates memory and invokes a constructor to initialize state. - In use — the object is reachable through one or more references and participates in your program.
- Garbage collection — once no live reference can reach the object, it becomes eligible for the garbage collector, which reclaims its memory at an unspecified later time.
Java has no explicit delete. You never free memory manually; you simply drop references (e.g., let them go out of scope or set them to null), and the JVM does the rest.
Warning: Do not rely on
finalize()for cleanup—it is deprecated and may never run. Usetry-with-resourcesand theAutoCloseableinterface for deterministic resource release.
The this Reference
Inside an instance method or constructor, this refers to the current object. It disambiguates a field from a parameter of the same name and lets a method return its own instance for fluent chaining.
public class Point {
private int x, y;
public Point setX(int x) {
this.x = x; // field 'x' = parameter 'x'
return this; // enable chaining
}
}
Access Modifiers
Access modifiers control the visibility of classes, fields, and methods. Choosing the tightest modifier that works is a hallmark of good design.
| Modifier | Same Class | Same Package | Subclass (other pkg) | Everywhere |
|---|---|---|---|---|
private | yes | no | no | no |
| default (no keyword) | yes | yes | no | no |
protected | yes | yes | yes | no |
public | yes | yes | yes | yes |
Tip: Default to
privatefor fields and widen only when a concrete need arises. Encapsulation is far easier to relax later than to tighten.
Best Practices
- Keep fields
private; expose behavior through methods, not raw state. - Give every class a single, clear responsibility.
- Initialize state fully in the constructor so objects are never in a half-built state.
- Use
thisto clarify intent, not as noise—reserve it for shadowing and fluent returns. - Favor immutability where practical; fewer mutable fields means fewer bugs.
- Never depend on garbage-collection timing for correctness.