This guide contains the most frequently asked Java interview questions and answers for developers with 2–3 years of experience. It covers Core Java, OOP Concepts, Collections Framework, Exception Handling, Multithreading, JVM Architecture, Class Loading, Java 8 Features, and other key topics commonly asked in technical interviews.
1) Method Overloading vs Method Overriding in Java
Introduction
Method Overloading and Method Overriding are two important concepts in Java that support Polymorphism. Although their names sound similar, they serve different purposes and work differently.
Method Overloading
Definition
Method Overloading occurs when multiple methods in the same class have the same name but different parameter lists.
This is also known as Compile-Time Polymorphism because the compiler determines which method to call during compilation.
Rules for Method Overloading
✅ Method name must be the same
✅ Parameters must be different:
- Different number of parameters
- Different data types
- Different order of parameters
✅ Return type may be different
❌ Changing only the return type is not considered overloading
Example
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
}
Output
Calculator calc = new Calculator();
System.out.println(calc.add(10, 20)); // 30
System.out.println(calc.add(10.5, 20.5)); // 31.0
System.out.println(calc.add(10, 20, 30)); // 60
Advantages of Overloading
- Improves code readability
- Increases code reusability
- Allows methods to perform similar operations with different inputs
Method Overriding
Definition
Method Overriding occurs when a child class provides its own implementation of a method that already exists in the parent class.
This is also known as Runtime Polymorphism because the method call is resolved during execution.
Rules for Method Overriding
✅ Requires inheritance
✅ Method name must be the same
✅ Parameters must be exactly the same
✅ Return type must be same or covariant
✅ Access modifier cannot be more restrictive
❌ Static methods cannot be overridden
❌ Final methods cannot be overridden
❌ Private methods cannot be overridden
Example
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
public class Test {
public static void main(String[] args) {
Animal animal = new Dog();
animal.sound();
}
}
Output
Dog barks
Why Runtime Polymorphism?
Animal animal = new Dog();
animal.sound();
Although the reference type is Animal, the actual object is Dog.
At runtime, Java determines which method implementation should be executed.
This process is called Dynamic Method Dispatch.
Comparison Table
| Feature | Method Overloading | Method Overriding |
|---|---|---|
| Definition | Same method name with different parameters | Same method implementation redefined in child class |
| Inheritance Required | No | Yes |
| Method Name | Same | Same |
| Parameters | Must be different | Must be same |
| Return Type | Can differ | Same or Covariant |
| Binding | Compile Time | Runtime |
| Polymorphism Type | Static Polymorphism | Dynamic Polymorphism |
| Performance | Faster | Slightly slower due to runtime resolution |
| Annotation | Not required | @Override recommended |
Interview Questions
1.1 Can we overload a method by changing only the return type?
No.
int add(int a, int b)
double add(int a, int b) // Compilation Error
The parameter list must be different.
1.2 Can static methods be overridden?
No.
Static methods belong to the class rather than objects.
class Parent {
static void show() {}
}
class Child extends Parent {
static void show() {}
}
This is called Method Hiding, not Overriding.
1.3 Can final methods be overridden?
No.
class Parent {
final void display() {
}
}
class Child extends Parent {
// Compilation Error
void display() {
}
}
1.4 Can private methods be overridden?
No.
Private methods are not inherited by child classes.
1.5 Can constructors be overloaded?
Yes.
class Employee {
Employee() {
}
Employee(int id) {
}
Employee(int id, String name) {
}
}
Constructors support overloading but not overriding.
Real-World Example
Consider a payment application.
Method Overloading
class PaymentService {
void pay(double amount) {
}
void pay(double amount, String couponCode) {
}
void pay(double amount, String couponCode, boolean useWallet) {
}
}
Same operation with different inputs.
Method Overriding
class Payment {
void processPayment() {
System.out.println("Generic Payment");
}
}
class CreditCardPayment extends Payment {
@Override
void processPayment() {
System.out.println("Credit Card Payment");
}
}
class UpiPayment extends Payment {
@Override
void processPayment() {
System.out.println("UPI Payment");
}
}
Same method with different implementations.
Key Takeaways
Method Overloading
- Same method name
- Different parameters
- Same class
- Compile-time polymorphism
- No inheritance required
Method Overriding
- Same method signature
- Child class redefines parent method
- Requires inheritance
- Runtime polymorphism
- Supports dynamic behavior
Easy Way to Remember
Overloading = Same Method + Different Inputs
Overriding = Same Method + Different Behavior
Example:
Overloading → One person speaking multiple languages.
Overriding → Son follows his own way instead of his father's way.
Both concepts are fundamental to writing flexible, reusable, and object-oriented Java applications.
2) What is a ClassLoader in Java?
Introduction
A ClassLoader in Java is a part of the Java Runtime Environment (JRE) responsible for loading Java classes into memory dynamically at runtime.
When a Java program starts, classes are not loaded into memory all at once. Instead, the JVM loads classes only when they are needed. This process is handled by the ClassLoader subsystem.
In simple terms:
A ClassLoader is a JVM component that loads
.classfiles into memory and makes them available for execution.
Why Do We Need a ClassLoader?
Consider the following code:
public class Main {
public static void main(String[] args) {
Employee emp = new Employee();
}
}
Before the JVM can create the Employee object:
- It must locate the
Employee.classfile. - Load the bytecode into memory.
- Verify the bytecode.
- Link the class.
- Initialize the class.
The ClassLoader performs these tasks automatically.
Class Loading Process
The JVM loads classes in three major phases:
1. Loading
The JVM reads the .class file and creates a corresponding Class object.
Class<?> cls = Employee.class;
At this stage, the bytecode is loaded into memory.
2. Linking
Linking consists of three steps:
Verification
Checks whether the bytecode is valid and secure.
Preparation
Allocates memory for static variables.
static int count;
Memory is allocated and initialized with default values.
Resolution
Converts symbolic references into direct memory references.
3. Initialization
Static variables and static blocks are executed.
class Employee {
static {
System.out.println("Class Initialized");
}
}
Output:
Class Initialized
Types of ClassLoaders in Java
Java uses a hierarchy of ClassLoaders.
Bootstrap ClassLoader
↑
Platform ClassLoader
↑
Application ClassLoader
1. Bootstrap ClassLoader
Responsibility
Loads core Java classes.
Examples:
java.lang.String
java.lang.Object
java.util.ArrayList
java.util.HashMap
Location
Loads classes from:
<JAVA_HOME>/lib
Example
System.out.println(String.class.getClassLoader());
Output:
null
Why null?
Bootstrap ClassLoader is implemented in native code and is not represented as a Java object.
2. Platform ClassLoader
Introduced in Java 9.
Responsibility
Loads Java platform modules and extension libraries.
Example
System.out.println(
java.sql.Driver.class.getClassLoader()
);
Typical Output:
jdk.internal.loader.ClassLoaders$PlatformClassLoader
3. Application ClassLoader
Also known as:
System ClassLoader
Responsibility
Loads classes available in:
Classpath
Examples:
- User-created classes
- Third-party libraries
- Maven dependencies
- Spring Boot classes
Example
System.out.println(
Employee.class.getClassLoader()
);
Output:
jdk.internal.loader.ClassLoaders$AppClassLoader
Parent Delegation Model
Java ClassLoaders follow the Parent Delegation Principle.
Before loading a class, a ClassLoader asks its parent to load it first.
Application ClassLoader
|
V
Platform ClassLoader
|
V
Bootstrap ClassLoader
Example
When loading:
String str = "Hello";
The Application ClassLoader asks:
- Platform ClassLoader
- Bootstrap ClassLoader
Bootstrap ClassLoader already knows about String.class, so it loads the class.
This prevents duplicate loading and improves security.
How to Check Which ClassLoader Loaded a Class?
public class Test {
public static void main(String[] args) {
System.out.println(
String.class.getClassLoader()
);
System.out.println(
Test.class.getClassLoader()
);
}
}
Output:
null
jdk.internal.loader.ClassLoaders$AppClassLoader
Custom ClassLoader
Java allows developers to create their own ClassLoaders.
Example use cases:
- Application servers
- Plugin architectures
- Hot deployment
- Dynamic module loading
- Security frameworks
Example:
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name)
throws ClassNotFoundException {
// Custom loading logic
return super.findClass(name);
}
}
Real-World Example
Spring Boot
When a Spring Boot application starts:
- JVM starts.
- Application ClassLoader loads Spring classes.
- Spring scans components.
- Classes are loaded dynamically.
- Beans are created.
Without ClassLoaders, dynamic frameworks like Spring would not work efficiently.
Interview Questions
2.1 What is a ClassLoader?
A ClassLoader is a JVM component responsible for loading Java classes into memory dynamically during runtime.
2.2 How many built-in ClassLoaders are there?
Three:
- Bootstrap ClassLoader
- Platform ClassLoader
- Application ClassLoader
2.3 What is Parent Delegation?
A mechanism where a ClassLoader delegates class-loading requests to its parent before attempting to load the class itself.
2.4 Why does String.class.getClassLoader() return null?
Because String is loaded by the Bootstrap ClassLoader, which is implemented in native code and not represented as a Java object.
2.5 Can we create a custom ClassLoader?
Yes.
By extending the ClassLoader class and overriding methods such as:
findClass()
loadClass()
ClassLoader vs JVM Memory Areas
| Component | Responsibility |
|---|---|
| ClassLoader | Loads classes into memory |
| Heap | Stores objects |
| Stack | Stores method calls and local variables |
| Method Area | Stores class metadata |
| Garbage Collector | Removes unused objects |
Key Takeaways
-
ClassLoader loads Java classes dynamically at runtime.
-
JVM uses lazy loading to improve performance.
-
Java provides three built-in ClassLoaders:
- Bootstrap
- Platform
- Application
-
ClassLoaders follow the Parent Delegation Model.
-
Custom ClassLoaders enable advanced features such as plugins and hot deployment.
-
Every Java application relies on ClassLoaders behind the scenes.
Easy Way to Remember
ClassLoader = Librarian of the JVM
Just as a librarian finds and brings the correct book
when requested, the ClassLoader finds and loads the
required class when the JVM needs it.
3) What is inheritance in Java?
Introduction
Inheritance is one of the four fundamental principles of Object-Oriented Programming (OOP).
Inheritance allows one class to acquire the properties and behaviors (fields and methods) of another class.
In simple terms:
Inheritance is a mechanism through which a child class can reuse the code of an existing parent class.
This promotes:
- Code Reusability
- Maintainability
- Extensibility
- Polymorphism
Real-Life Example
Consider a family relationship:
Parent
│
▼
Child
A child inherits characteristics from its parent.
Similarly in Java:
Animal
│
▼
Dog
The Dog class inherits properties and methods from the Animal class.
Syntax of Inheritance
Java uses the extends keyword.
class Parent {
// properties and methods
}
class Child extends Parent {
// additional properties and methods
}
Basic Example
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.bark();
}
}
Output
Animal is eating
Dog is barking
How Inheritance Works
Diagram
+----------------+
| Animal |
+----------------+
| + eat() |
+----------------+
▲
│ extends
│
+----------------+
| Dog |
+----------------+
| + bark() |
+----------------+
The Dog class can use:
- Its own methods
- Methods inherited from
Animal
Why Use Inheritance?
Without inheritance:
class Dog {
void eat() {
System.out.println("Animal is eating");
}
void bark() {
System.out.println("Dog barking");
}
}
class Cat {
void eat() {
System.out.println("Animal is eating");
}
void meow() {
System.out.println("Cat meowing");
}
}
Problem:
- Duplicate code
- Difficult maintenance
With inheritance:
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
}
class Cat extends Animal {
}
Benefit:
- Reusable code
- Cleaner design
Types of Inheritance in Java
Java supports inheritance through classes and interfaces.
1. Single Inheritance
One child inherits from one parent.
Diagram
Animal
│
▼
Dog
Example
class Animal {
void eat() {
}
}
class Dog extends Animal {
void bark() {
}
}
2. Multilevel Inheritance
A class inherits from another child class.
Diagram
Animal
│
▼
Dog
│
▼
Puppy
Example
class Animal {
void eat() {
}
}
class Dog extends Animal {
void bark() {
}
}
class Puppy extends Dog {
void play() {
}
}
3. Hierarchical Inheritance
Multiple child classes inherit from the same parent.
Diagram
Animal
/ | \
/ | \
▼ ▼ ▼
Dog Cat Lion
Example
class Animal {
void eat() {
}
}
class Dog extends Animal {
}
class Cat extends Animal {
}
class Lion extends Animal {
}
4. Multiple Inheritance (Through Interfaces)
Java does not support multiple inheritance with classes.
❌ Not Allowed
class A {
}
class B {
}
class C extends A, B {
}
Reason:
The Diamond Problem.
Multiple Inheritance Using Interfaces
✅ Allowed
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck implements Flyable, Swimmable {
public void fly() {
System.out.println("Flying");
}
public void swim() {
System.out.println("Swimming");
}
}
The Diamond Problem
Imagine:
Animal
/ \
/ \
▼ ▼
Bird Fish
\ /
\ /
Duck
If both Bird and Fish have the same method:
void move()
Which implementation should Duck inherit?
To avoid this ambiguity, Java does not allow multiple inheritance with classes.
The super Keyword
The super keyword is used to access parent class members.
Access Parent Method
class Animal {
void sound() {
System.out.println("Animal Sound");
}
}
class Dog extends Animal {
void sound() {
super.sound();
System.out.println("Dog Bark");
}
}
Output:
Animal Sound
Dog Bark
Call Parent Constructor
class Animal {
Animal() {
System.out.println("Animal Constructor");
}
}
class Dog extends Animal {
Dog() {
super();
System.out.println("Dog Constructor");
}
}
Output:
Animal Constructor
Dog Constructor
Inheritance and Method Overriding
Inheritance enables Runtime Polymorphism through Method Overriding.
class Animal {
void sound() {
System.out.println("Animal Sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog Bark");
}
}
Real-World Example
Banking Application
Account
▲
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
SavingsAccount CurrentAccount LoanAccount
Parent Class
class Account {
void deposit() {
System.out.println("Deposit Money");
}
void withdraw() {
System.out.println("Withdraw Money");
}
}
Child Class
class SavingsAccount extends Account {
void calculateInterest() {
System.out.println("Calculating Interest");
}
}
Benefit:
- Common functionality remains in one place.
- Child classes add specialized behavior.
Advantages of Inheritance
Code Reusability
Write once, use many times.
Easy Maintenance
Changes in parent class are inherited automatically.
Better Code Organization
Common functionality stays in the parent class.
Supports Polymorphism
Allows dynamic method dispatch.
Extensibility
New child classes can be added easily.
Disadvantages of Inheritance
Tight Coupling
Child classes depend heavily on parent classes.
Reduced Flexibility
Changes in parent class may affect all child classes.
Deep Hierarchies Become Complex
Too many inheritance levels make maintenance difficult.
Interview Questions
3.1 What is Inheritance?
Inheritance is a mechanism that allows one class to acquire the properties and methods of another class.
3.2 Which keyword is used for inheritance?
extends
3.3 Does Java support multiple inheritance?
No, not through classes.
Java supports multiple inheritance using interfaces.
3.4 What is the advantage of inheritance?
- Code reuse
- Better maintainability
- Supports polymorphism
3.5 What is the difference between Inheritance and Composition?
Inheritance
IS-A Relationship
Example:
Dog IS-A Animal
Composition
HAS-A Relationship
Example:
Car HAS-A Engine
Inheritance vs Composition
| Feature | Inheritance | Composition |
|---|---|---|
| Relationship | IS-A | HAS-A |
| Coupling | Tight | Loose |
| Reusability | High | High |
| Flexibility | Less | More |
| Preferred in Modern Design | No | Yes |
Key Takeaways
-
Inheritance is an OOP concept that enables code reuse.
-
Java uses the
extendskeyword for inheritance. -
A child class inherits fields and methods from a parent class.
-
Java supports:
- Single Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
-
Multiple inheritance is supported through interfaces.
-
Inheritance is the foundation for Method Overriding and Runtime Polymorphism.
-
Modern application design often prefers Composition over deep inheritance hierarchies.
Easy Way to Remember
Inheritance = "IS-A" Relationship
Dog IS-A Animal
Car IS-A Vehicle
Manager IS-A Employee
Composition = "HAS-A" Relationship
Car HAS-A Engine
House HAS-A Room
Computer HAS-A CPU
A simple rule:
If one object "is a type of" another object, use Inheritance.
If one object "contains" another object, use Composition.
4) Why can’t we override a static method?
Static methods belong to the class, not the object. Overriding is based on runtime polymorphism, but static method binding happens at compile time.
A same-signature static method in child class results in method hiding, not overriding.
5) What is Dynamic Method Dispatch?
It’s runtime selection of an overridden method implementation based on the actual object, not the reference type.
6) What is Java Classpath?
Classpath tells the JVM where to find classes and libraries (directories/JARs) required for execution.
7) What does the volatile keyword do?
volatile ensures visibility of changes to a variable across threads (reads/writes go to main memory). It does not make compound operations (like count++) atomic.
8) When does finally not execute?
finally generally executes, except when the JVM exits abruptly, e.g. System.exit(0) (or a fatal crash).
9) StringBuffer vs StringBuilder
- StringBuffer: synchronized, thread-safe, slower.
- StringBuilder: not synchronized, faster, preferred in single-thread contexts.
10) Vector vs ArrayList
- Vector: synchronized (thread-safe), slower.
- ArrayList: not synchronized, faster, most commonly used.
11) Why is String immutable?
Key reasons:
- String pool sharing
- Security (classpath, reflection, etc.)
- Hash caching (e.g.,
HashMapkeys) - Thread-safety
12) HashMap vs HashSet
- HashMap stores key-value pairs; keys must be unique.
- HashSet stores only unique values (internally uses a
HashMap).
13) Producer–Consumer problem & benefits
A concurrency pattern where:
- Producer produces items into a buffer
- Consumer consumes items
Typical implementations use blocking queues (BlockingQueue) or wait/notify.
Benefits:
- Decouples producer and consumer
- Improves throughput
- Cleaner concurrent design
14) How to create an immutable class?
- Make class
final - Make fields
private final - No setters
- Initialize via constructor
- Return defensive copies for mutable fields
15) Fail-fast vs Fail-safe iterators
- Fail-fast: throws
ConcurrentModificationExceptionon structural modification (e.g., ArrayList iterator). - Fail-safe: iterates over a copy (e.g.,
CopyOnWriteArrayList), doesn’t throw CME.
16) What is an interface? Features?
An interface defines a contract.
- Supports multiple inheritance of type
- Can have default and static methods (Java 8+)
- Variables are
public static finalby default
17) SOLID principles
- SRP: one reason to change
- OCP: open for extension, closed for modification
- LSP: substitutability
- ISP: small focused interfaces
- DIP: depend on abstractions
18) What is the difference between == and equals()?
==compares references (same object?)equals()compares logical equality (can be overridden)
19) What is the instanceof operator?
Checks if an object is an instance of a class/interface. Helps avoid ClassCastException during casting.
20) super keyword use cases
- Access parent members
- Call parent method
- Invoke parent constructor via
super()
21) What is finalize()? Why discouraged?
finalize() may be called by GC before object removal, but it’s unpredictable and deprecated in modern Java. Prefer try-with-resources and explicit cleanup.
22) What are the main Collections Framework interfaces?
Collection→List,Set,QueueMap(separate hierarchy)
23) What is a Thread?
A lightweight unit of execution. Java supports multithreading via Thread and Runnable.
24) How to create a thread?
- Extend
Thread - Implement
Runnable - (Modern) Use
ExecutorService
25) What is deadlock? How to avoid?
Deadlock happens when threads wait on each other forever.
Avoid using:
- consistent lock ordering
- timeouts (
tryLock) - minimizing nested locks
26) What is synchronization?
Ensures only one thread accesses critical section at a time to prevent data inconsistency.
27) Shallow copy vs deep copy
- Shallow: copies references
- Deep: copies nested objects too
28) What are annotations used for?
Metadata for:
- compiler checks (
@Override) - runtime frameworks (Spring/Hibernate)
- documentation
29) What is the Java Memory Model (JMM)?
Defines rules for visibility, ordering, and atomicity in multi-threaded Java.
30) What is reflection?
Inspect/modify classes/methods/fields at runtime (java.lang.reflect). Useful for frameworks; use carefully due to performance/security.
31) What does join() do?
Makes the current thread wait until the target thread finishes.
32) Benefits of Java Stream API
- concise functional operations
- lazy evaluation
- easy parallelization
33) What is try-with-resources?
Introduced in Java 7; automatically closes resources implementing AutoCloseable.
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
// use resource
}
34) Comparable vs Comparator
- Comparable (
compareTo) defines natural ordering inside the class - Comparator (
compare) defines external/custom ordering
35) What is a Queue?
FIFO data structure (Queue interface). Implementations: LinkedList, ArrayDeque, PriorityQueue.
36) What is clone()?
Creates a copy of an object. Default is shallow copy; requires Cloneable and overriding carefully. Often better to use copy constructors/factories.
37) What are default methods in interfaces?
Java 8 feature to add new methods to interfaces without breaking existing implementations.
38) What are checked vs unchecked exceptions?
- Checked: must be handled/declared (
IOException) - Unchecked: runtime (
NullPointerException)
39) Difference between throw and throws
throw: actually throws an exceptionthrows: declares a method may throw exceptions
40) What is Optional?
Optional is a container to represent presence/absence of value, reducing null handling errors.
41) What is a functional interface?
An interface with exactly one abstract method (e.g., Runnable, Callable, Function). Used for lambdas.
42) What are lambda expressions?
A concise way to implement functional interfaces.
43) What is a marker interface?
An empty interface used to convey metadata (e.g., Serializable, historically Cloneable).
44) What is serialization?
Converting object into byte stream for storage/transfer (Serializable). Use carefully; consider security implications.
45) What is the difference between HashMap and ConcurrentHashMap?
HashMap: not thread-safeConcurrentHashMap: thread-safe with better concurrency; avoids locking entire map
46) What is the difference between ArrayList and LinkedList?
ArrayList: fast random access, slower middle insertsLinkedList: faster inserts/removes in middle, slower random access
47) What is the difference between map() and flatMap() in streams?
map: one-to-one transformflatMap: one-to-many then flattens
48) What is a race condition?
When multiple threads access shared data and the final result depends on timing/order. Prevent using synchronization/locks/atomic classes.
49) What are atomic classes?
Classes like AtomicInteger providing lock-free thread-safe operations using CAS (compare-and-swap).
50) JVM vs JRE vs JDK
- JVM: runs bytecode
- JRE: JVM + standard libraries
- JDK: JRE + developer tools (javac, debugger, etc.)
Want a printable version?
If you want, I can also generate a PDF-style version (clean formatting) or split this into multiple posts (Core Java / Collections / Concurrency).