home / java interview / core-java-coding-must-do
Java Interview

Core Java Coding (Must Do)

1). Singleton Class

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

2). Immutable Class

An Immutable Class is a class whose objects cannot be modified after they are created. If you want to change a value, you create a new object instead of modifying the existing one.

Rules to Create an Immutable Class

1. Make the class final

This prevents inheritance, which could allow mutability.

public final class Employee {
}

2. Make all fields private and final

private final int id;
private final String name;

3. Initialize fields only through the constructor

public Employee(int id, String name) {
    this.id = id;
    this.name = name;
}

4. Do not provide setter methods

❌ Wrong

public void setName(String name) {
    this.name = name;
}

✅ No setters.


5. Return defensive copies of mutable objects

If your class contains mutable fields like Date, List, Map, etc., don’t expose the original reference.

Example 1 (Simple Immutable Class)

public final class Employee {

    private final int id;
    private final String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

We make an immutable class final to prevent inheritance. Otherwise, a subclass could add mutable state or override methods, breaking the immutability guarantee. Marking the class final ensures no one can extend it and change its behavior.

Usage

Employee emp = new Employee(101, "Prakash");

System.out.println(emp.getId());
System.out.println(emp.getName());

The object can never be changed.


Example 2 (Mutable Object Problem)

Suppose we have:

private final Date joiningDate;

Wrong implementation:

public Date getJoiningDate() {
    return joiningDate;
}

Someone can modify it:

Date d = employee.getJoiningDate();
d.setTime(0);

Now the employee object has changed!


Correct Implementation (Defensive Copy)

Constructor

public Employee(Date joiningDate) {
    this.joiningDate = new Date(joiningDate.getTime());
}

Getter

public Date getJoiningDate() {
    return new Date(joiningDate.getTime());
}

Now nobody can modify the internal object.


Example 3 (List Defensive Copy)

Wrong

private final List<String> skills;

public Employee(List<String> skills) {
    this.skills = skills;
}

Caller can modify it:

skills.add("Spring Boot");

Correct

public final class Employee {

    private final List<String> skills;

    public Employee(List<String> skills) {
        this.skills = List.copyOf(skills);
    }

    public List<String> getSkills() {
        return skills;
    }
}

List.copyOf() creates an unmodifiable copy.