Java Interview Questions and Answers — Part 1

Java interview questions for 2026 (part 1): JVM, OOP, static, polymorphism, and core APIs—grouped questions with answers.

Published

Updated

Read time 31 min read

Reviewed byDeepak Prasad

Java Interview Questions and Answers — Part 1

Java interviews test whether you understand how the language actually runs—bytecode on the JVM, object lifecycle, inheritance traps, and the static/instance boundary—not whether you can recite keyword lists from memory. Experienced loops often start with fundamentals and then push into design: "Why would this cause a NullPointerException?" or "When would you pick composition over inheritance?"

This page is part one of a two-part set (53 questions here). It covers JVM basics, OOP, constructors, static members, polymorphism, and abstract classes. Continue with part two for collections, garbage collection, threading, and Java 8+ features. For a dedicated OOP and OOPs prep guide (four pillars, SOLID, design patterns, Java OOPs depth), see OOP interview questions. For C and C++ interview questions (pointers, memory, RAII), see C and C++ interview questions. For Spring Boot framework depth, see Spring Boot interview questions for experienced developers. For Selenium and Java UI automation (WebDriver, TestNG, POM), see Selenium interview questions. For full-stack integration questions, see full stack developer interviews.

NOTE
Prep tip: Open each answer after you try the question yourself. Narrate your reasoning aloud—interviewers care as much about how you think as about the final keyword.

Interview context and how to prepare

What do Java interviews test in part one?

Part one is the foundation layer. Interviewers use it to see whether you can reason about Java before diving into frameworks like Spring.

Topics you should expect:

Area What interviewers probe
Platform JDK vs JRE vs JVM, bytecode, class loading
OOP Inheritance, polymorphism, abstraction, encapsulation
Object model Constructors, this/super, static vs instance
Design basics Abstract classes vs interfaces, overriding rules

How depth changes by level:

  • Fresher / junior — syntax, definitions, small code traces
  • Experienced — same topics with follow-ups: thread-safety, design trade-offs, production bugs
How should you use this two-part Java guide?

Use both parts as a structured drill, not a single cram session.

Part Coverage When to focus
Part 1 (this page) JVM, OOP, static, polymorphism, abstract classes Week 1–2 if basics are rusty
Part 2 Collections, GC, exceptions, threading, lambdas, records Week 2–4; highest ROI for experienced roles

Suggested split if you already ship production Java:

  • ~40% on part one (fill gaps, fix misconceptions)
  • ~60% on part two (collections, concurrency, modern Java)

Daily habit: For each question, answer out loud in 60–90 seconds, then open the collapsed answer and compare structure—not just keywords.


JVM, platform, and class loading

What is the difference between JDK and JRE?

Think of the JDK as the full developer toolkit and the JRE as the runtime slice needed to execute compiled programs.

Component Full name What it includes
JDK Java Development Kit Compiler (javac), debugger, libraries, and a JRE
JRE Java Runtime Environment JVM + core libraries to run bytecode (no compiler)

Interview framing:

  • You develop with the JDK (javac produces .class files).
  • You run with the JRE/JVM (java MyApp loads bytecode).
  • Modern JDK distributions (11+) often ship as a single download—the JRE is not always a separate install.

A strong answer is:

The JDK is for development—it includes the compiler and tools. The JRE is the runtime that executes bytecode on the JVM. In practice I install a JDK because it contains both.

What is Java Virtual Machine (JVM)?

The JVM is the engine that loads bytecode, verifies it, and executes it. Your .java source compiles to platform-independent bytecode; a JVM implementation for your OS (Linux, Windows, macOS) runs that bytecode on real hardware.

What the JVM does at a high level:

  1. Load classes (via class loaders)
  2. Verify bytecode safety
  3. Execute (interpret or JIT-compile to native code)
  4. Manage memory (heap, stacks, garbage collection)

Each platform has its own JVM implementation, which is why Java is "write once, run anywhere" at the bytecode layer—not because .class files run natively on every CPU.

A strong answer is:

The JVM is the runtime that executes Java bytecode. It handles class loading, verification, execution, and memory management—the bridge between portable bytecode and the underlying operating system.

What are the different types of memory areas allocated by JVM?

The JVM divides memory into areas with different lifetimes and purposes. Knowing them helps you reason about leaks, stack overflows, and GC behavior.

Memory area Purpose
Method area (metaspace) Class metadata, runtime constant pool, method bytecode
Heap Object instances and arrays (shared across threads)
Stack (per thread) Local variables, partial results, method call frames
PC register (per thread) Address of the current bytecode instruction
Native method stack Support for JNI / native code

Class loaders (Bootstrap, Platform/Extension, Application) load .class files into the method area—they are not separate "memory pools" but are often discussed alongside JVM layout.

For OS-level memory visibility, see check memory usage per process on Linux.

A strong answer is:

The heap holds objects, each thread gets its own stack for locals and calls, and class metadata lives in the method area. OutOfMemoryError on the heap and StackOverflowError on deep recursion are the classic symptoms of getting these wrong.

What is JIT compiler?

JIT (Just-In-Time) compilation converts hot bytecode paths to native machine code while the program runs, instead of interpreting every instruction forever.

Why it matters in interviews:

  • Cold code may start interpreted; frequently executed methods get optimized.
  • This is why micro-benchmarks that run once can mislead you—JIT needs warmup.
  • JVM vendors (HotSpot, GraalVM) differ in optimization details, but the concept is universal.

JIT is enabled by default on HotSpot and is a major reason Java can be competitive on long-running server workloads.

A strong answer is:

The JIT compiler translates frequently executed bytecode to native code at runtime for better performance. I mention warmup when discussing benchmarks—first runs are not representative of steady-state server load.

How Java platform is different from other platforms?

Many languages compile to native machine code for one OS/CPU. Java compiles to bytecode that any compliant JVM can run.

Approach Portability
C/C++ native binary Tied to target OS/ABI—you rebuild per platform
Java bytecode + JVM Same .class / JAR can run anywhere a JVM exists

Trade-off: you depend on a JVM runtime and accept some startup/warmup cost in exchange for portability and a rich standard library.

A strong answer is:

Java targets the JVM with bytecode, not a specific CPU/OS binary. That portability is the platform difference—one build artifact runs on any machine with a compatible JVM.

Why people say that Java is 'write once and run anywhere' language?

The slogan refers to bytecode portability, not magic immunity from platform differences.

How it works:

  1. You write .java source once.
  2. javac compiles to bytecode (.class).
  3. Any JVM on Linux, Windows, or macOS can load and run that bytecode.

Caveats interviewers like to hear:

  • File paths, line endings, and native libraries still differ by OS.
  • You still test on target platforms for I/O, networking, and JNI.
  • JVM version matters—bytecode targets a class file version.

A strong answer is:

Write once, run anywhere means bytecode runs on any JVM. I still validate on target platforms because filesystem, native libs, and JVM version can change behavior.

How does ClassLoader work in Java?

Class loaders find bytecode (classpath, modules, JARs) and define Class objects in the JVM. Loading is usually lazy—classes load when first referenced.

Three classic loaders (parent-delegation model):

Loader Loads
Bootstrap Core JDK classes (java.*) from rt / modules
Platform (Extension) Extension libraries (jre/lib/ext legacy; modules in modern JDK)
Application (System) Your classes and dependencies on the classpath / module path

Delegation rule: A loader asks its parent first. This prevents you from replacing core java.lang.String with your own copy.

Interview follow-up: Custom class loaders appear in app servers, OSGi, and some serialization/security scenarios.

A strong answer is:

Class loaders load bytecode on demand using parent delegation—bootstrap for core JDK classes, application loader for my code on the classpath. I mention delegation when discussing class isolation in containers or plugins.


Language basics and main method

Do you think ‘main’ used for main method is a keyword in Java?

No. main is not a keyword—it is simply the method name the JVM launcher looks for when you run java MyClass.

You can define other methods named main in the same class (unusual but legal). What matters is the signature the launcher expects:

java
public static void main(String[] args)

A strong answer is:

main is a convention enforced by the JVM launcher, not a Java keyword. The required signature is public, static, void, and accepts a String array.

Can we write main method as public void static instead of public static void?

No. Modifier order can vary (static public is fine), but return type must come after modifiers.

Valid:

java
public static void main(String[] args) { }
static public void main(String[] args) { }

Invalid:

java
public void static main(String[] args) { }  // compile error

A strong answer is:

Modifiers can be reordered, but return type follows modifiers. public void static is illegal because void ends up in the wrong position.

In Java, if we do not specify any value for local variables, then what will be the default value of the local variables?

Local variables have no default value. If you declare a local variable and use it before assigning, the compiler reports an error—not a null at runtime.

java
void demo() {
    int count;
    // System.out.println(count);  // compile error: variable count might not have been initialized
}

Contrast with fields (instance/static variables): Those get default values (0, false, null).

This distinction trips people up in interviews—always separate locals from fields.

A strong answer is:

Locals must be assigned before use; the compiler enforces that. Only fields get default initialization—null for references, zero for numbers, false for booleans.

Let say, we run a java class without passing any arguments. What will be the value of String array of arguments in Main method?

When you run java MyApp with no args, args is a zero-length array, not null.

java
public static void main(String[] args) {
    System.out.println(args.length);  // 0
    System.out.println(args == null); // false
}

Safe pattern: iterate args without a null check; length 0 means no arguments.

A strong answer is:

args is an empty String array with length 0, never null. I can loop over args directly when parsing CLI flags.

What is the difference between byte and char data types in Java?

Both are integral types, but they represent different things.

Type Size Range / role
byte 8 bits -128 to 127 — raw binary numeric data
char 16 bits UTF-16 code unit — character/text data ('A', '\u0041')

Interview note: char is unsigned (0–65535). byte is signed. Neither is for everyday text processing—use String for that.

A strong answer is:

byte is an 8-bit signed integer; char is a 16-bit UTF-16 character. I use String for text and byte[] for raw binary data.


OOP principles and inheritance

What are the main principles of Object Oriented Programming?

The four pillars interviewers expect you to name and apply, not just list:

Principle One-line meaning Interview signal
Encapsulation Hide internal state; expose behavior via methods Private fields + getters/setters, invariants
Abstraction Show essential behavior, hide complexity Interfaces, abstract classes, service APIs
Inheritance Reuse and extend behavior (IS-A) Parent/child classes—use sparingly
Polymorphism Same interface, different implementations Overriding, interface types

A strong answer is:

I name all four, then give a concrete example—encapsulation with private fields, polymorphism with an interface type holding different implementations.

What is the difference between Object Oriented Programming language and Object Based Programming language?
OOP language (Java, C++) Object-based (JavaScript historically, VBScript)
Inheritance Class-based inheritance supported Often prototype-based; limited class inheritance
Polymorphism Full compile-time + runtime polymorphism More dynamic; patterns differ
Encapsulation Strong with classes, access modifiers Possible with objects/closures

Modern JavaScript has classes, but Java interviews still use this question to check whether you understand full OOP vs "objects without a rigid class model."

A strong answer is:

OOP languages like Java support class inheritance and polymorphism as first-class features. Object-based languages may have objects and encapsulation but weaker or different inheritance models.

Why do we need constructor in Java?

A constructor initializes a new object's state when new runs. It has the same name as the class and no return type.

Why it matters:

  • Sets required fields and invariants before other methods run
  • Can overload constructors for different creation paths
  • Can call this(...) or super(...) to chain setup

Default constructor: If you define no constructors, Java provides a public no-arg constructor. If you add any constructor, the default is not generated—you must define no-arg explicitly if callers need it.

A strong answer is:

Constructors initialize object state at creation time. I remember that adding any custom constructor removes the implicit default unless I declare one myself.

Explain the concept of Inheritance?

Inheritance lets a child class reuse and extend a parent class—an IS-A relationship (Dog extends Animal).

Benefits:

  • Code reuse for shared behavior
  • Polymorphism—treat child as parent type
  • Method overriding for specialized behavior

Risks (mention in experienced loops):

  • Fragile base class—parent changes break children
  • Deep hierarchies hurt readability
  • Prefer composition when behavior is "HAS-A" not "IS-A"

A strong answer is:

Inheritance models IS-A relationships for reuse and polymorphism. I also mention composition when the relationship is really HAS-A or when hierarchies would get deep.

Why Java does not support multiple inheritance?

Java allows a class to extend only one superclass. Multiple inheritance of classes was omitted to avoid the diamond problem: if two parents implement the same method differently, which version does the child inherit?

Classic ambiguity example: Class C extends A, B and both A and B define foo()—the compiler cannot pick a single override.

What Java allows instead:

  • A class implements multiple interfaces
  • Default methods on interfaces (Java 8+) with explicit conflict resolution rules

A strong answer is:

Java avoids multiple class inheritance because of diamond ambiguity. I use interfaces—and default methods when needed—to combine multiple contracts without inheriting conflicting class implementations.

How aggregation and composition are different concepts?

Both are HAS-A associations; strength of ownership differs.

Relationship Lifetime Example
Composition Strong—part dies with whole Car has Engine; no car means no car-engine
Aggregation Weak—parts can outlive container University has Student; student exists without university

Interview tip: Composition supports encapsulation—you control how internal parts are created and exposed.

A strong answer is:

Composition is strong ownership—the part cannot exist without the whole. Aggregation is weaker—the contained object can outlive the container. I pick composition when lifecycle must be tied together.


Constructors, this, and super

Why do we need default constructor in Java classes?

The default constructor is the no-argument constructor Java generates when you define no constructors at all.

Rules to remember:

Situation What Java does
No constructors written Compiler adds public ClassName() { }
Any constructor written Default is not generated—you must add no-arg yourself if needed
Subclass with no constructors Compiler adds default that calls super() on parent

Why it matters in interviews:

  • Frameworks (JPA, Jackson, Spring) often need a no-arg constructor to create instances via reflection.
  • If you only define Person(String name), callers cannot write new Person() unless you add an explicit no-arg constructor.
java
public class Person {
    private String name;

    public Person(String name) { this.name = name; }
    // No default constructor — new Person() will not compile
}

A strong answer is:

Java supplies a public no-arg constructor only when I define none. The moment I add any constructor, I must declare a no-arg one myself if frameworks or callers need it.

Why constructors cannot be final, static, or abstract in Java?

Constructors are special instance-initialization methods. Three modifiers are illegal for different reasons:

Modifier Why it is illegal
final Constructors are not inherited or overridden—final adds nothing
abstract Abstract means "no body"; every constructor must have a body to run when new executes
static Static belongs to the class; constructors exist to initialize a specific new object
java
// All compile errors:
// public final MyClass() { }
// public abstract MyClass();
// public static MyClass() { }

A strong answer is:

Constructors initialize instances at new time—they need a body, cannot be class-level static methods, and are never overridden so final is meaningless.

What is the purpose of 'this' keyword in java?

this refers to the current object instance—the one whose method or constructor is running.

Common uses:

Use Example
Disambiguate fields from parameters this.name = name;
Constructor chaining this(otherArg) must be first statement
Pass current object registerListener(this);
Call overridden method on current class this.print() (not super)
java
public class Account {
    private final String id;

    public Account(String id) {
        this.id = id;           // field vs parameter
    }

    public Account() {
        this("default");        // chain to other constructor
    }
}

A strong answer is:

this is the current instance—I use it to resolve name clashes, chain constructors, or pass the object to another method. In an override scenario, this calls the child's version; super calls the parent's.

What is the purpose of 'super' keyword in java?

super refers to the immediate parent class from a child class method or constructor.

Two main jobs:

  1. super(...) — call a parent constructor (must be first statement if used).
  2. super.method() — invoke an overridden parent method from the child.
java
public class Dog extends Animal {
    public Dog(String name) {
        super(name);            // parent constructor
    }

    @Override
    public void speak() {
        super.speak();          // parent behavior, then extend
        System.out.println("Woof");
    }
}

Note: If you omit super() in a child constructor, Java inserts a call to the parent's no-arg constructor automatically.

A strong answer is:

super reaches into the parent—either to run its constructor with super(...) or to call an overridden method with super.method(). I use it when the child extends rather than replaces parent behavior.

Is it possible to use this() and super() both in same constructor?

No. A constructor may call either this(...) or super(...) as its first statement—not both in the same constructor.

Why: Both delegate object setup to another constructor. The JVM must pick one path before any other statements run.

java
public class Child extends Parent {
    public Child() {
        super(1);    // OK — first statement
        // this(2);  // compile error if super() already used
    }

    public Child(int x) {
        this();      // chains to no-arg constructor above
    }
}

Chaining can still reach both parent and child logic indirectly: this() → another constructor → super().

A strong answer is:

this() and super() cannot appear together in one constructor because only one can be the first statement. I chain through another constructor if I need both parent and child setup paths.


Memory model and references

Why there are no pointers in Java?

Java exposes object references, not raw memory addresses you can arithmetic on.

What you get instead of C-style pointers:

Pointer feature Java equivalent
Address arithmetic Not available
Manual free() Garbage collector reclaims unreachable objects
Dereference any address Only through typed references
Move objects in memory JVM may relocate objects; references stay valid

Benefits: Safer code, simpler memory management and garbage collection, and fewer segfault-class bugs.

java
String s = new String("hi");  // s is a reference, not an address you can increment
// s++;  // not legal

A strong answer is:

Java gives me references to objects, not manipulable pointers. The JVM owns memory layout and GC, which trades low-level control for safety and portability.

If there are no pointers in Java, then why do we get NullPointerException?

Programmers work with references; the JVM still uses pointers internally. A reference is either:

  • Non-null — points at a live object (or array).
  • null — points at nothing.

NullPointerException (NPE) fires when you dereference a null reference—calling a method, reading a field, or indexing as if an object exists.

java
String s = null;
int len = s.length();   // NPE — no object behind the reference

Person p = getPerson();   // might return null from a DAO
p.getName();              // classic production NPE

Interview follow-up: Use Optional, null checks, or validation at API boundaries to avoid NPEs in production.

A strong answer is:

References are the programmer-facing view of object locations. NPE means I tried to use a reference that points to no object—null is a valid reference value, but you cannot call methods on it.

What is the meaning of object cloning in Java?

Cloning creates a new object copy from an existing one. The standard hook is Object.clone(), which performs a shallow copy by default.

Aspect Detail
Shallow clone Copies field values; reference fields still point to same nested objects
Deep clone Nested objects copied too—usually custom logic or serialization
Contract Class should implement Cloneable; override clone() and call super.clone()
Return type Object.clone() returns Object—cast or override with covariant return
java
public class Employee implements Cloneable {
    private String name;
    private int[] scores;

    @Override
    public Employee clone() throws CloneNotSupportedException {
        Employee copy = (Employee) super.clone();  // shallow
        copy.scores = scores.clone();            // deep-copy array
        return copy;
    }
}

Modern alternative: Copy constructors or factory methods are often clearer than Cloneable.

A strong answer is:

Cloning duplicates an object; default clone() is shallow. For interview depth I mention deep vs shallow copy and that copy constructors are often preferable to Cloneable.


Static members and initialization

In Java, why do we use static variable?

A static variable belongs to the class, not to any single instance. All objects share one copy.

When to use:

Use case Example
Shared configuration MAX_CONNECTIONS
Counters across instances totalInstancesCreated
Constants public static final int DEFAULT_PORT = 8080
java
public class ConnectionPool {
    private static int activeCount = 0;  // one value for entire JVM class

    public ConnectionPool() {
        activeCount++;
    }
}

Memory note: Static fields live for the class loader's lifetime (often application lifetime), not per object.

A strong answer is:

Static variables hold class-wide state shared by every instance. I use them for constants and true shared counters—not for per-object data that should stay encapsulated.

Why it is not a good practice to create static variables in Java?

Mutable static state is a common source of bugs, tight coupling, and test pain.

Problems:

Issue Why it hurts
Global mutable state Any code can change it—hard to reason about order of updates
Thread safety Shared writes need synchronization or atomics
Testing Tests leak state unless you reset static fields between runs
Hidden dependencies Instance methods secretly depend on class-level globals
OOP friction Behavior tied to class instead of object lifecycle

Better patterns: Inject dependencies, use instance fields, or confine mutable state to well-defined singletons with clear lifecycle.

A strong answer is:

Static mutable variables are global variables in disguise. I avoid them unless the value is truly constant or I have a deliberate, thread-safe singleton design.

What is the purpose of static method in Java?

A static method belongs to the class. You call it on the class name without creating an instance.

Good fits:

  • Utility functions (Math.max, Collections.sort)
  • Factory methods (Optional.of, List.of)
  • Behavior that does not need instance fields
java
public class StringUtils {
    public static boolean isBlank(String s) {
        return s == null || s.trim().isEmpty();
    }
}

// StringUtils.isBlank(" ");   no object needed

Restriction: Static methods can access only static members directly; instance fields require an object reference.

A strong answer is:

Static methods express class-level behavior that does not depend on a particular object's state. I keep them stateless utilities when possible.

Why do we mark main method as static in Java?

The JVM launches your program before any object of your class exists. It needs an entry point it can call on the class, not on an instance.

java
public class App {
    public static void main(String[] args) {
        System.out.println("JVM calls this without new App()");
    }
}

If main were instance method: The launcher would need to know which constructor to use to create the first object—ambiguous and unnecessary.

A strong answer is:

main is static because the JVM starts execution without constructing an object. The launcher invokes App.main(args) on the class itself.

In what scenario do we use a static block?

A static initializer block runs once when the class is first loaded—before any static method or constructor on that class.

Use when:

  • Static fields need non-trivial setup (read config, register drivers)
  • One-time class-level registration
java
public class DbConfig {
    private static final Properties props;

    static {
        props = new Properties();
        try (var in = DbConfig.class.getResourceAsStream("/db.properties")) {
            props.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}

Order: Static fields and static blocks run top-to-bottom, then the class is ready. Static blocks run before main.

A strong answer is:

Static blocks initialize complex class-level state once at class load time—things too heavy for a one-line field initializer.

What happens when static modifier is not mentioned in the signature of main method?

The JVM looks for:

java
public static void main(String[] args)
Scenario Result
public void main(String[] args) Compiles but fails at runtime
Run with java MyClass NoSuchMethodError: main

The launcher cannot call an instance method without first creating an object—and it does not create one for you.

A strong answer is:

Without static, main is just another instance method. The program may compile, but the JVM entry point is missing so you get NoSuchMethodError at launch.

What is the difference between static method and instance method in Java?
Static method Instance method
Belongs to Class Specific object
Call syntax ClassName.method() object.method()
Can use instance fields? Only via an object reference Yes, on this
Can use static fields? Yes Yes
Polymorphism Resolved by reference type (hiding) Resolved by runtime object type (overriding)
java
public class Counter {
    private int count = 0;
    private static int total = 0;

    public void increment() { count++; total++; }      // instance
    public static int getTotal() { return total; }     // static — no this.count
}

A strong answer is:

Static methods are class utilities; instance methods operate on object state. Static methods cannot touch instance fields without an object reference.

Are we allowed to override a static method in Java?

No. Static methods are not polymorphic in the override sense. A subclass method with the same signature hides the parent's static method—it does not override it.

java
class Parent {
    public static void greet() { System.out.println("Parent"); }
}

class Child extends Parent {
    public static void greet() { System.out.println("Child"); }  // hiding, not overriding
}

Parent p = new Child();
p.greet();           // prints "Parent" — compile-time binding
Child.greet();       // prints "Child"

Rule: @Override on a static method is a compile error. Instance methods use dynamic dispatch; static methods use static binding on the reference type.

A strong answer is:

You cannot override static methods—you can only hide them. Which method runs is chosen at compile time from the reference type, not the runtime object.


Polymorphism and binding

What is the difference between method overloading and method overriding in Java?
Overloading Overriding
Where Same class (or inherited + new overloads) Parent and child in inheritance
Signature Same name, different parameters Same name and parameters
Binding Compile time (static) Runtime (dynamic)
Return type Can differ independently Covariant return allowed (subtype)
Access Any visibility Cannot reduce visibility
java
// Overloading
void print(int x) { }
void print(String s) { }

// Overriding
class Animal { void speak() { } }
class Dog extends Animal { @Override void speak() { } }

A strong answer is:

Overloading is same name, different parameters, resolved at compile time. Overriding is same signature in a subclass, resolved at runtime based on the actual object type.

What is meant by covariant return type in Java?

Since Java 5, an overriding method may return a narrower (subtype) return type than the parent method. That is a covariant return type.

java
class Animal {
    Animal reproduce() { return new Animal(); }
}

class Dog extends Animal {
    @Override
    Dog reproduce() { return new Dog(); }  // covariant — Dog is subtype of Animal
}

Before Java 5: Override required the exact same return type.

Applies to: Reference return types in overrides—not primitives (you cannot covariant int to long in an override).

A strong answer is:

Covariant return lets a subclass override with a more specific return type—Dog instead of Animal—while keeping the same method signature otherwise.

What is Runtime Polymorphism?

Runtime polymorphism (dynamic polymorphism) means the JVM picks which overridden instance method to run based on the actual object type, not the reference type.

java
Animal a = new Dog();
a.speak();   // Dog.speak() runs at runtime

void process(Animal animal) {
    animal.speak();  // could be Cat, Dog, etc.—resolved when call executes
}

Requires: Inheritance + instance method override + assignment to a supertype reference.

Not runtime polymorphic: Static methods (hiding), fields (hidden not overridden), overloaded methods (compile-time choice).

A strong answer is:

Runtime polymorphism is dynamic dispatch on overridden instance methods—the JVM calls the version belonging to the real object, even when the variable is typed as the parent.

Explain the difference between static and dynamic binding?

Binding is when the JVM/compiler links a call site to the method implementation.

Static binding Dynamic binding
When resolved Compile time Runtime
Applies to Static methods, final methods, private methods, overloaded methods Overridden instance methods
Decision based on Reference type Actual object type
java
class A { void m() { } static void s() { } }
class B extends A { void m() { } static void s() { } }

A ref = new B();
ref.m();   // dynamic — B.m()
ref.s();   // static  A.s()

Interview trap: Overloading is always static binding—the compiler picks the overload from argument types at compile time.

A strong answer is:

Static binding fixes the target at compile time—overloads, static methods, final methods. Dynamic binding defers overridden instance methods until runtime based on the real object.


Abstraction, interfaces, and annotations

What is Abstraction in Object Oriented programming?

Abstraction hides implementation complexity and exposes only what callers need.

In practice:

Mechanism What caller sees
Abstract class Partial implementation + abstract hooks
Interface Contract of operations
Public API Methods on a concrete class; internals private
java
// Caller knows pay() — not how card vs wallet differs
public interface PaymentGateway {
    void pay(Money amount);
}

Not the same as: abstract class keyword—that is one Java language tool for abstraction, not the OOP concept itself.

A strong answer is:

Abstraction is a design idea—show essential behavior, hide how it works. Interfaces and abstract classes are Java mechanisms that implement abstraction.

How is Abstraction different from Encapsulation?

Both reduce complexity, but at different angles:

Abstraction Encapsulation
Focus What to expose vs hide Bundling data + behavior; guarding access
Level Design / API shape Implementation / access control
Typical tools Interfaces, abstract classes, layering private fields, getters/setters, immutability
java
public class BankAccount {
    private BigDecimal balance;           // encapsulation — field hidden

    public void deposit(BigDecimal amt) { /* rules inside */ }  // abstracted operation
}

Relationship: Good encapsulation supports abstraction—you cannot hide implementation without controlling access.

A strong answer is:

Abstraction is about the simplified view you offer. Encapsulation is about locking internal state behind controlled access—private fields and public methods.

What is an abstract class in Java?

An abstract class cannot be instantiated directly. It may declare abstract methods (no body) and provide concrete shared code for subclasses.

Rules:

Rule Detail
Instantiation new AbstractClass() is illegal
Subclass duty Non-abstract child must implement all abstract methods
Abstract method No body; child provides implementation
Can have Fields, constructors, concrete methods
java
public abstract class Shape {
    protected String color;

    public abstract double area();   // subclass must implement

    public String getColor() { return color; }  // shared concrete code
}

A strong answer is:

An abstract class is a partial base—you cannot new it, but subclasses inherit shared code and must fill in abstract methods.

Is it allowed to mark a method abstract as well as final?

No. The modifiers contradict each other.

Modifier Meaning
abstract Subclass must provide implementation
final Subclass cannot override
java
// public abstract final void draw();  // compile error

Same logic applies to abstract static or abstract private (in older Java)—abstract methods must be overridable by subclasses.

A strong answer is:

abstract means "subclass implements me"; final means "nobody overrides me." A method cannot be both.

How Annotations are better than Marker Interfaces?

Marker interfaces (e.g., Serializable) tag a type with no methods—metadata encoded only as "implements X."

Annotations carry richer, flexible metadata:

Feature Marker interface Annotation
Data payload None Attributes (@RequestMapping("/api"))
Target Types only Methods, fields, parameters, etc.
Retention policy Always on type SOURCE / CLASS / RUNTIME
Tooling instanceof checks Reflection, bytecode processors, frameworks
java
@Deprecated
@SuppressWarnings("unchecked")
@Entity
public class User { }

Trade-off: Marker interfaces are visible in type signatures; annotations can be quieter but depend on runtime scanning.

A strong answer is:

Annotations beat marker interfaces when I need configurable metadata on methods or fields, retention control, and framework processing—not just a type tag with no data.

What is the difference between abstract class and interface in Java?
Abstract class Interface
Inheritance extends one class implements multiple interfaces
State Instance fields allowed Only public static final constants
Constructors Yes No
Method bodies Concrete + abstract methods Abstract (implicit), default, static (Java 8+)
Best for Shared base implementation Cross-cutting contracts

Modern Java (8+): Interfaces can have default and static methods—so "only abstract methods" is outdated for interviews.

Design heuristic:

  • IS-A with shared code → abstract class
  • CAN-DO capability → interface (Comparable, Runnable)

A strong answer is:

Abstract classes anchor a family with shared state and constructors. Interfaces define capabilities you can mix in—multiple per class—with defaults for optional behavior since Java 8.

How can we cast to an object reference to an interface reference?

If a class implements an interface, every instance is-a implementor of that interface. You can assign or cast to the interface type without changing the object—only the compile-time view.

java
class ArrayList<E> implements List<E> { /* ... */ }

List<String> list = new ArrayList<>();   // widening to interface — preferred

ArrayList<String> arr = new ArrayList<>();
List<String> view = (List<String>) arr;   // explicit cast  usually redundant here

Rules:

  • Upcast (class → interface it implements): always safe, often implicit.
  • Downcast (interface → concrete class): needs instanceof check or you risk ClassCastException.
java
void process(List<String> list) {
    if (list instanceof ArrayList<String> al) {
        al.trimToSize();   // safe downcast
    }
}

A strong answer is:

Any object whose class implements an interface can be referenced through that interface. Upcast is automatic; downcast to a concrete class requires that the object actually is that type.


Packages and core classes

What is the purpose of package in Java?

A package groups related types and controls naming and visibility.

Why packages matter:

Purpose Benefit
Organization com.app.service, com.app.model mirror domain structure
Name uniqueness Two User classes can coexist in different packages
Access control Package-private (default) scope limits cross-package access
Encapsulation Hide implementation packages from public API surface
java
package com.example.billing;

import com.example.billing.model.Invoice;

public class BillingService { }

Convention: Reverse DNS (com.company.product) avoids global name clashes.

A strong answer is:

Packages namespace and organize code, prevent class name collisions, and enforce access boundaries—not just folder structure.

What is java.lang package?

java.lang is imported implicitly into every compilation unit. It holds core language types.

Notable classes:

Class Role
Object Root of all classes
String, StringBuilder Text
Integer, Long, Boolean, … Wrapper types
Math Numeric helpers
System out, err, gc(), currentTimeMillis()
Throwable, Exception, Error Exception hierarchy
Class, Runtime Reflection and runtime

You never need import java.lang.Object;—it is always available.

A strong answer is:

java.lang is the automatic core package—Object, String, wrappers, System, and the exception hierarchy. Every Java file sees it without an explicit import.

Which is the most important class in Java?

Open-ended—but java.lang.Object is the standard strong answer.

Why Object matters:

Feature Impact
Root of class hierarchy Every class extends Object (directly or indirectly)
equals / hashCode Collection correctness
toString Logging and debugging
getClass Reflection entry point
wait / notify Intrinsic locking (legacy coordination)
java
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Person other)) return false;
    return Objects.equals(id, other.id);
}

Alternate answers (if you justify them): String for immutability interviews, Class for reflection-heavy roles.

A strong answer is:

Object is the root of every class and defines equals, hashCode, and toString contracts that ripple through collections and debugging—I treat it as the most foundational class.

Can you import same package or class twice in your class?

Duplicate imports are harmless. The compiler collapses them—no error, no extra bytecode.

java
import java.util.List;
import java.util.List;   // redundant but legal
Scenario Result
Same import twice Ignored silently
Same class loaded at runtime Class loader loads once per loader
Two classes, same simple name Compile error unless you use fully qualified name for one
java
import java.util.Date;
// import java.sql.Date;  // clash  use FQCN for one of them

Part two: Continue with Java Interview Questions and Answers — Part 2 for collections, garbage collection, exceptions, threading, and Java 8+ features.

A strong answer is:

Importing the same type twice is a no-op. Real problems come from simple-name collisions between two different classes with the same short name.


Concurrency preview

What is a Thread in Java?

A thread is a lightweight unit of execution within a process. Multiple threads share the process heap but each has its own stack and program counter.

Basics:

Concept Detail
vs process Threads share memory; processes are isolated
Java model java.lang.Thread or executor frameworks
Default JVM starts one thread to run main
Concurrency goal Overlap I/O or parallelize CPU work (with care)
java
Thread t = new Thread(() -> System.out.println("Running in worker"));
t.start();   // async — does not block caller after start()

// Prefer executors in production:
ExecutorService pool = Executors.newFixedThreadPool(4);

Preview only here: Thread lifecycle, synchronization, and java.util.concurrent are covered in part two.

A strong answer is:

A thread is an independent execution path inside the JVM process—main is one thread; I create more for concurrent work, with shared heap and per-thread stacks.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …