04 - Classes, Objects, and Methods
A complete beginner-to-advanced guide to Java's object model, aligned with the Oracle Certified Professional: Java SE 21 Developer (1Z0-830) exam objectives.
Table of Contents
- Classes and Objects
- Fields (Instance Variables)
- Methods
- Method Overloading
- The
thisKeyword - Constructors
- Constructor Chaining
- Encapsulation
- Static Members
- Instance vs Static
- Initialization Order
- Varargs
- Pass-by-Value
- Certification Traps
- Common Mistakes
- Interview Questions
- Quick Revision Notes
- One-Page Cheat Sheet
1. Classes and Objects
A class is a blueprint. An object is a real instance built from that blueprint.
CLASS (blueprint) OBJECTS (instances)
+----------------+ +-------+ +-------+ +-------+
| Car | new --> | car1 | | car2 | | car3 |
| - color | |red | |blue | |black |
| - speed | |120 | |90 | |150 |
| + drive() | +-------+ +-------+ +-------+
+----------------+
public class Car {
String color; // field
int speed; // field
void drive() { // method
System.out.println(color + " car driving at " + speed);
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car(); // create object
car1.color = "Red";
car1.speed = 120;
car1.drive(); // Red car driving at 120
}
}
| Term | Meaning |
|---|---|
| Class | Template defining fields + methods. |
| Object | Concrete instance created with new. |
| Reference | A variable that points to an object. |
new | Operator that allocates an object on the heap. |
2. Fields (Instance Variables)
Fields hold an object's state. Each object gets its own copy.
public class Student {
String name; // instance field
int age; // instance field
double gpa; // instance field
}
Default Values (Fields Only)
| Field Type | Default |
|---|---|
int, short, byte, long | 0 / 0L |
float, double | 0.0 |
char | '\u0000' |
boolean | false |
Reference (objects, String) | null |
Student s = new Student();
System.out.println(s.name); // null
System.out.println(s.age); // 0
System.out.println(s.gpa); // 0.0
Trap: Fields are auto-initialized; local variables are not and must be assigned before use.
3. Methods
A method is a reusable block of code that performs an action and optionally returns a value.
Anatomy
public static int add(int a, int b) {
| | | | | |
modifier static return name parameters body
| type
public class Calculator {
int add(int a, int b) { // returns int
return a + b;
}
void greet() { // returns nothing
System.out.println("Hi");
}
}
Rules
| Rule | Detail |
|---|---|
| Return type required | Use void if nothing is returned. |
return in non-void | Must return a compatible value on every path. |
| Parameters are local | They exist only inside the method. |
| Method signature | Name + parameter list (types & order). Return type is not part of it. |
4. Method Overloading
Overloading = multiple methods with the same name but different parameter lists (number, type, or order).
public class Printer {
void print(int x) { System.out.println("int: " + x); }
void print(double x) { System.out.println("double: " + x); }
void print(String x) { System.out.println("String: " + x); }
void print(int x, int y) { System.out.println("two ints"); }
}
What Counts as a Different Signature?
| Changes the signature? | |
|---|---|
| Different number of params | ✅ Yes |
| Different parameter types | ✅ Yes |
| Different parameter order (different types) | ✅ Yes |
| Different return type only | ❌ No (won't compile) |
| Different parameter names only | ❌ No |
| Different access modifier only | ❌ No |
// int sum(int a, int b) { ... }
// double sum(int a, int b) { ... } // ERROR: return type alone is not enough
Overload Resolution Order (Trap)
When multiple overloads could match, the compiler picks in this priority:
1. Exact match
2. Widening (int -> long -> double)
3. Autoboxing (int -> Integer)
4. Varargs (int... )
void test(long x) { System.out.println("long"); }
void test(Integer x) { System.out.println("Integer"); }
void test(int... x) { System.out.println("varargs"); }
test(5); // prints "long" — widening beats boxing beats varargs
Java prefers widening over autoboxing, and both over varargs, which is the last resort.
5. The this Keyword
this refers to the current object. Use it to disambiguate fields from parameters, or to call another constructor.
public class Point {
int x, y;
Point(int x, int y) {
this.x = x; // this.x = field, x = parameter
this.y = y;
}
Point moveBy(int dx, int dy) {
this.x += dx;
this.y += dy;
return this; // enable method chaining
}
}
Use of this | Purpose |
|---|---|
this.field | Refer to the instance field (not a local/param). |
this() | Call another constructor in the same class. |
return this; | Return the current object (fluent API). |
Pass this | Hand the current object to another method. |
Trap:
thiscannot be used in astaticcontext — static methods have no current object.
6. Constructors
A constructor initializes a new object. It has the same name as the class and no return type.
public class Person {
String name;
int age;
Person() { // no-arg constructor
this.name = "Unknown";
this.age = 0;
}
Person(String name, int age) { // parameterized constructor
this.name = name;
this.age = age;
}
}
Key Rules
| Rule | Detail |
|---|---|
| Same name as class | And no return type (not even void). |
| Default constructor | If you write no constructor, the compiler adds a no-arg one. |
| No default if you define any | Writing any constructor removes the auto-generated no-arg one. |
| Can be overloaded | Multiple constructors with different params. |
| Access modifiers | Can be public, protected, default, or private. |
The "Method-Looking Constructor" Trap
public class Box {
int size;
void Box() { // This is a METHOD, not a constructor (has void)!
size = 10;
}
}
// new Box() uses the DEFAULT constructor; size stays 0, not 10
If it has a return type (even
void), it's a method, not a constructor — a classic exam trap.
private Constructors
Used in singletons and utility classes to prevent external instantiation:
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {} // no one else can call new
public static Singleton getInstance() { return INSTANCE; }
}
7. Constructor Chaining
Constructors can call other constructors to avoid duplicate code.
this() — Same Class
public class Rectangle {
int width, height;
Rectangle() {
this(1, 1); // calls the two-arg constructor
}
Rectangle(int side) {
this(side, side); // calls the two-arg constructor
}
Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}
super() — Parent Class
class Animal {
Animal(String name) { System.out.println("Animal: " + name); }
}
class Dog extends Animal {
Dog() {
super("Dog"); // must be the FIRST statement
System.out.println("Dog created");
}
}
Chaining Rules (Heavily Tested)
| Rule | Detail |
|---|---|
this() / super() must be first | And only one of them, as the first statement. |
Implicit super() | If you don't call this()/super(), the compiler inserts super() (no-arg). |
| Parent needs accessible no-arg ctor | If the parent has only parameterized constructors, the child must call super(args) explicitly. |
| No recursion | this() calling itself in a cycle = compile error. |
class Base {
Base(int x) { } // no no-arg constructor
}
class Derived extends Base {
Derived() { // ERROR: implicit super() has no match
} // must write super(someInt);
}
8. Encapsulation
Encapsulation = hiding internal state behind a controlled interface. Make fields private, expose public getters/setters.
public class BankAccount {
private double balance; // hidden state
public double getBalance() { // controlled read
return balance;
}
public void deposit(double amount) { // controlled write + validation
if (amount > 0) {
balance += amount;
}
}
}
Benefits
| Benefit | Why It Matters |
|---|---|
| Validation | Setters enforce rules (e.g., no negative balance). |
| Flexibility | Internal representation can change without breaking callers. |
| Read-only / write-only | Provide only a getter or only a setter. |
| Maintainability | Clear, controlled access points. |
Immutability (Strong Encapsulation)
public final class Money { // final: cannot be subclassed
private final double amount; // final: set once
private final String currency;
public Money(double amount, String currency) {
this.amount = amount;
this.currency = currency;
}
public double getAmount() { return amount; }
public String getCurrency() { return currency; }
// no setters -> immutable
}
A record (Java 16+) provides this immutable pattern automatically:
record Money(double amount, String currency) {}.
9. Static Members
static members belong to the class, not to instances. There is exactly one shared copy.
public class Counter {
static int count = 0; // shared by all objects
int id; // unique per object
Counter() {
count++; // increments shared counter
id = count;
}
static int getCount() { // static method
return count;
}
}
new Counter();
new Counter();
System.out.println(Counter.getCount()); // 2
Static Method Rules
| Rule | Detail |
|---|---|
No this | Static methods have no current object. |
| No direct instance access | Can't use instance fields/methods without an object. |
| Access via class | Counter.getCount() (preferred over instance access). |
| Cannot be overridden | Static methods are hidden, not overridden (resolved by type). |
Trap: Static Accessed via Instance
Counter c = new Counter();
System.out.println(c.count); // legal but MISLEADING — it's a class variable
// Prefer: Counter.count
Trap: Accessing Instance from Static
public class Demo {
int x = 5;
public static void main(String[] args) {
// System.out.println(x); // ERROR: non-static x in static context
System.out.println(new Demo().x); // OK
}
}
10. Instance vs Static
class BankAccount
+-----------------------------+
| static double interestRate | <-- ONE shared copy
+-----------------------------+
/ \
acc1 / \ acc2
+----------------+ +----------------+
| double balance | | double balance | <-- each object's OWN copy
+----------------+ +----------------+
| Aspect | Instance Member | Static Member |
|---|---|---|
| Belongs to | Object | Class |
| Copies | One per object | One total |
| Accessed via | Object reference | Class name |
Uses this? | Yes | No |
| Created when | Object is built | Class is loaded |
| Memory | Heap (with object) | Method area (class) |
11. Initialization Order
One of the most-tested topics. Memorize the exact order.
The Rule
WHEN CLASS IS FIRST LOADED (once):
1. static fields + static blocks -> in SOURCE ORDER
WHEN AN OBJECT IS CREATED (every new):
2. instance fields + instance blocks -> in SOURCE ORDER
3. constructor body
Summary: Static (once) → Instance fields/blocks → Constructor.
Single Class Example
public class InitDemo {
static int s = log("1 static field");
static { log("2 static block"); }
int i = log("4 instance field");
{ log("5 instance block"); }
InitDemo() { log("6 constructor"); }
static int log(String m) { System.out.println(m); return 0; }
public static void main(String[] args) {
log("3 main starts");
new InitDemo();
}
}
Output:
1 static field
2 static block
3 main starts
4 instance field
5 instance block
6 constructor
With Inheritance
class Parent {
static { System.out.println("P-static"); }
{ System.out.println("P-instance"); }
Parent() { System.out.println("P-ctor"); }
}
class Child extends Parent {
static { System.out.println("C-static"); }
{ System.out.println("C-instance"); }
Child() { System.out.println("C-ctor"); }
}
// new Child() prints:
// P-static, C-static (all statics first, parent before child, ONCE)
// P-instance, P-ctor (parent object init)
// C-instance, C-ctor (child object init)
Order with inheritance: Parent static → Child static → (per object) Parent instance + ctor → Child instance + ctor.
12. Varargs
Varargs (...) let a method accept a variable number of arguments.
public class MathUtil {
static int sum(int... numbers) { // numbers is treated as int[]
int total = 0;
for (int n : numbers) total += n;
return total;
}
}
MathUtil.sum(); // 0 (empty)
MathUtil.sum(1, 2, 3); // 6
MathUtil.sum(new int[]{4,5}); // 9 (array also works)
Rules
| Rule | Detail |
|---|---|
| Must be last parameter | void m(String s, int... n) — varargs goes last. |
| Only one varargs per method | void m(int... a, int... b) is illegal. |
| Treated as an array | Inside the method it's a normal array. |
| Lowest overload priority | Varargs is chosen only if no fixed-arity match exists. |
// void print(int a, int... b) {}
// void print(int... a) {}
// print(1); // AMBIGUOUS in some cases -> compile error
13. Pass-by-Value
Java is always pass-by-value. For objects, the reference value (the pointer) is copied — not the object.
static void changePrimitive(int x) {
x = 100; // changes only the local copy
}
static void changeReference(StringBuilder sb) {
sb.append(" World"); // modifies the SAME object (state change)
sb = new StringBuilder("New"); // reassigns local copy only
}
public static void main(String[] args) {
int n = 5;
changePrimitive(n);
System.out.println(n); // 5 (unchanged)
StringBuilder s = new StringBuilder("Hello");
changeReference(s);
System.out.println(s); // "Hello World" (state changed, not reassigned)
}
| Passed | What's Copied | Can Method Change Original? |
|---|---|---|
| Primitive | The value | ❌ No |
| Object reference | The reference (pointer) | ✅ State yes; ❌ reassignment no |
Key: You can mutate the object a reference points to, but reassigning the parameter doesn't affect the caller's variable.
14. Certification Traps
| # | Trap |
|---|---|
| 1 | A "constructor" with a return type (even void) is actually a method. |
| 2 | Defining any constructor removes the auto-generated no-arg constructor. |
| 3 | If the parent has no no-arg constructor, the child must call super(args). |
| 4 | this() / super() must be the first statement in a constructor. |
| 5 | Overloading by return type only does not compile. |
| 6 | Overload resolution: widening → boxing → varargs (in that priority). |
| 7 | this cannot be used in a static context. |
| 8 | Accessing a non-static field from static main = compile error. |
| 9 | Static methods are hidden, not overridden (resolved by reference type). |
| 10 | Local variables have no defaults; fields do. |
| 11 | Init order: static (once) → instance fields/blocks → constructor; parent before child. |
| 12 | Varargs must be the last parameter; only one allowed. |
| 13 | Java is pass-by-value; reassigning a parameter never affects the caller. |
| 14 | Static field accessed via instance reference is legal but misleading. |
| 15 | final fields must be assigned exactly once (declaration, init block, or every constructor). |
15. Common Mistakes
| Mistake | Fix |
|---|---|
| Giving a constructor a return type | Remove it; constructors have no return type. |
Forgetting super(args) for a parameterized parent | Call it explicitly as the first line. |
Making fields public | Use private + getters/setters (encapsulation). |
Using this in a static method | Remove this; pass an object instead. |
| Overloading by changing only return type | Change the parameter list. |
| Expecting a method to change a passed primitive | It can't — Java is pass-by-value. |
| Assuming static state is per-object | Static is shared across all instances. |
Putting this()/super() not first | Move it to the first statement. |
16. Interview Questions
Q1. Difference between a class and an object?
A class is a blueprint defining structure and behavior; an object is a concrete instance created from it with new.
Q2. What is a constructor and how does it differ from a method? A constructor initializes a new object, shares the class name, and has no return type. A method has a return type and performs general behavior.
Q3. What happens if you don't define any constructor? The compiler provides a default no-arg constructor. If you define any constructor, that default is no longer generated.
Q4. What is constructor chaining?
Calling one constructor from another using this() (same class) or super() (parent), which must be the first statement.
Q5. What is method overloading? Multiple methods with the same name but different parameter lists. Return type alone does not differentiate them.
Q6. Explain the overload resolution order. Exact match → widening → autoboxing → varargs.
Q7. What is encapsulation and why is it useful?
Hiding internal state via private fields and exposing controlled access through getters/setters; enables validation, flexibility, and maintainability.
Q8. Difference between static and instance members? Static members belong to the class with one shared copy; instance members belong to each object with separate copies.
Q9. Why can't a static method access instance variables directly?
Static methods have no this (no associated object), so there is no instance to read the field from.
Q10. What is the initialization order in Java? Static fields/blocks once (in order), then per object: instance fields/blocks (in order), then the constructor body — parent before child.
Q11. Is Java pass-by-value or pass-by-reference? Always pass-by-value. For objects, the reference value is copied, so you can mutate the object but not reassign the caller's variable.
Q12. What are varargs and what are their rules?
A way to accept variable arguments using ...; must be the last parameter, only one per method, and treated as an array internally.
17. Quick Revision Notes
- Class = blueprint; object = instance created with
new. - Fields get defaults (0/false/null); local variables do not.
- Method signature = name + parameter list (not return type).
- Overloading: different parameter list; return type alone is invalid.
- Resolution: exact → widening → boxing → varargs.
this= current object; not allowed in static context.- Constructor: class name, no return type; a return type makes it a method.
- No constructor written → compiler adds no-arg; writing any removes that default.
this()/super()must be the first statement; implicitsuper()is inserted otherwise.- Parent without no-arg constructor forces explicit
super(args). - Encapsulation:
privatefields + public getters/setters; immutable viafinal. - Static = one shared copy at class level; no
this; hidden not overridden. - Init order: static (once) → instance fields/blocks → constructor; parent before child.
- Varargs: last parameter, one only, acts as an array, lowest overload priority.
- Java is pass-by-value; reassigning parameters never affects callers.
18. One-Page Cheat Sheet
==================== CLASSES, OBJECTS & METHODS CHEAT SHEET ====================
CLASS vs OBJECT
class = blueprint ; object = new Class() ; reference points to object
FIELDS (instance) DEFAULTS (fields only, not locals)
one copy per object int=0 double=0.0 boolean=false ref=null
METHODS
modifier returnType name(params){...}
signature = name + params (NOT return type)
OVERLOADING
same name, different params (count/type/order)
return-type-only difference -> ERROR
resolution: EXACT -> WIDENING -> BOXING -> VARARGS
this
this.field / this() / return this ; NOT in static context
CONSTRUCTORS
same name as class, NO return type (return type => it's a METHOD!)
no ctor written -> compiler adds no-arg ; write any -> default removed
can overload ; can be private (singleton/util)
CHAINING
this(...) same class | super(...) parent ; MUST be first statement
no this()/super() -> implicit super() inserted
parent has only param ctor -> child MUST call super(args)
order: Parent-static->Child-static -> Parent-inst+ctor -> Child-inst+ctor
ENCAPSULATION
private fields + public get/set ; validate in setters
immutable: final class + final fields + no setters (or use record)
STATIC vs INSTANCE
static: one copy, class-level, no this, hidden not overridden
instance: per object, needs object reference
non-static field from static main -> ERROR
INIT ORDER
1. static fields + static blocks (ONCE, source order)
2. instance fields + instance blocks (per object, source order)
3. constructor body
VARARGS
type... name -> LAST param, only one, acts as array, lowest priority
PASS-BY-VALUE (always)
primitive: copy of value (caller unchanged)
object: copy of reference (can mutate state, reassign does NOT affect caller)
===============================================================================
End of 04 - Classes, Objects, and Methods.