Skip to content
Java interview 7 min read

Core Java Interview Questions

Whether you are preparing for your first software role or targeting a senior engineer position, Java interviews tend to revisit the same foundational concepts — sometimes shallow, sometimes deep. This section collects the most commonly asked Core Java questions, explains the reasoning interviewers are looking for, and points you to focused sub-pages on OOP, Collections, and Concurrency.

What Interviewers Actually Test

Java interviews are rarely just “name the method.” Interviewers want to see that you understand why the language works the way it does. The questions cluster around a few recurring themes:

  • Language fundamentals — types, scope, memory, pass-by-value
  • Object-oriented design — inheritance, polymorphism, abstraction, encapsulation
  • Core APIs — Strings, exceptions, I/O, Collections
  • Concurrency — threads, locks, the Java Memory Model
  • Modern Java — generics, lambdas, streams, records (Java 16+), virtual threads (Java 21)

The questions below are the ones that come up most often, across both phone screens and on-site rounds.


Frequently Asked Core Java Questions

1. Is Java pass-by-value or pass-by-reference?

Java is always pass-by-value. For primitives, the value itself is copied. For objects, the reference (memory address) is copied — meaning you can mutate the object’s fields inside a method, but you cannot make the caller’s variable point to a different object.

public class PassByValue {
    static void tryToReassign(StringBuilder sb) {
        sb.append(" World");          // visible to caller — same object
        sb = new StringBuilder("X"); // NOT visible — local copy only
    }

    public static void main(String[] args) {
        StringBuilder s = new StringBuilder("Hello");
        tryToReassign(s);
        System.out.println(s); // Hello World
    }
}

Output:

Hello World

See Call by Value for the full breakdown.


2. What is the difference between == and .equals()?

== compares references (are both variables pointing to the exact same object in memory?). .equals() compares logical content (do the two objects represent the same value?).

public class EqualityDemo {
    public static void main(String[] args) {
        String a = new String("hello");
        String b = new String("hello");

        System.out.println(a == b);       // false — different objects
        System.out.println(a.equals(b));  // true  — same content
    }
}

Output:

false
true

Tip: Always override both equals() and hashCode() together. Objects that are .equals() must return the same hashCode(), otherwise HashMap and HashSet will behave incorrectly.


3. Why is String immutable in Java?

Once created, a String object’s character sequence can never change. Three key reasons:

  1. Security — class names, network URLs, and file paths are passed as Strings. Mutability would open attack vectors.
  2. String Pool efficiency — because Strings are immutable, the JVM can safely cache them in the String Pool. Multiple variables can share the same literal without risk.
  3. Thread safety — an immutable object is inherently safe to share between threads with no synchronization.
String s = "Java";
s.concat(" 21");       // returns a NEW String; s is unchanged
System.out.println(s); // Java

Output:

Java

Read more at Why String is Immutable.


4. What is the difference between final, finally, and finalize?

Keyword / MethodWhere it livesWhat it does
finalmodifier on class/method/variablePrevents inheritance / overriding / reassignment
finallyexception handling blockAlways executes after try/catch, used for cleanup
finalize()Object methodCalled by GC before collecting an object — deprecated in Java 9, removed in Java 18
public class FinalDemo {
    public static void main(String[] args) {
        final int MAX = 100;     // constant — cannot reassign
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
        } finally {
            System.out.println("finally always runs");
        }
    }
}

Output:

Caught: / by zero
finally always runs

Details: final Keyword, finally Block, final vs finally vs finalize.


5. What is autoboxing and unboxing?

Autoboxing is the automatic conversion of a primitive (e.g. int) to its wrapper class (Integer). Unboxing is the reverse. The compiler inserts the conversion calls invisibly.

import java.util.ArrayList;

public class AutoboxDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(42);          // autoboxing: int → Integer
        int val = list.get(0); // unboxing:   Integer → int
        System.out.println(val);
    }
}

Output:

42

Warning: Autoboxing inside tight loops creates many short-lived objects. Prefer primitive arrays or streams when performance matters.

Full page: Autoboxing & Unboxing.


6. What is the difference between checked and unchecked exceptions?

CheckedUnchecked
ExtendsException (not RuntimeException)RuntimeException
Must handle?Yes — compile error if ignoredNo — optional
ExamplesIOException, SQLExceptionNullPointerException, ArrayIndexOutOfBoundsException
import java.io.*;

public class ExceptionTypes {
    // checked — compiler forces you to declare or handle it
    static void readFile() throws IOException {
        new FileReader("missing.txt"); // IOException is checked
    }

    public static void main(String[] args) {
        String s = null;
        // unchecked — no compiler warning
        System.out.println(s.length()); // NullPointerException at runtime
    }
}

More on the topic: Exception Handling, Custom Exceptions.


7. Explain static vs instance members

A static member belongs to the class — it is shared across all instances and exists even before any object is created. An instance member belongs to a specific object.

public class Counter {
    static int total = 0; // shared across all Counter objects
    int id;               // unique per object

    Counter() {
        total++;
        this.id = total;
    }

    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
        System.out.println("Total: " + Counter.total); // 2
        System.out.println("c1.id: " + c1.id);        // 1
        System.out.println("c2.id: " + c2.id);        // 2
    }
}

Output:

Total: 2
c1.id: 1
c2.id: 2

See static Keyword for the full picture.


8. What is the Java Memory Model (JMM)?

The JMM defines the rules for how threads interact through memory. Key guarantees:

  • Visibility — changes made by one thread are not guaranteed to be visible to another unless there is a happens-before relationship.
  • volatile — declares that reads/writes go directly to main memory, establishing happens-before between writer and reader.
  • synchronized — establishes happens-before at monitor enter/exit, ensuring both visibility and atomicity.
public class VolatileDemo {
    private static volatile boolean stop = false;

    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            while (!stop) { /* spin */ }
            System.out.println("Stopped");
        });
        worker.start();
        Thread.sleep(100);
        stop = true; // visible to worker because of volatile
    }
}

Read: Java Memory Model, volatile Keyword.


9. What is the difference between an abstract class and an interface?

This is one of the most common OOP questions. The short answer: use an abstract class when you want to share state or partial implementation; use an interface when you want to define a contract that unrelated classes can implement.

FeatureAbstract ClassInterface
Multiple inheritanceNoYes (multiple interfaces)
ConstructorYesNo
Instance fieldsYesNo (only static final)
Default methodsYes (Java 8+)Yes (Java 8+)
Access modifiers on methodsAnypublic by default

See Abstract Class vs Interface for detailed examples.


10. What are lambda expressions and when should you use them?

Introduced in Java 8, a lambda is a concise way to pass behavior as data. It implements a functional interface — an interface with exactly one abstract method.

import java.util.*;

public class LambdaDemo {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Charlie", "Alice", "Bob");

        // Before Java 8
        Collections.sort(names, new Comparator<String>() {
            public int compare(String a, String b) { return a.compareTo(b); }
        });

        // Java 8+ lambda
        names.sort((a, b) -> a.compareTo(b));
        System.out.println(names);
    }
}

Output:

[Alice, Bob, Charlie]

Deep dive: Lambda Expressions, Stream API.


Tips for Answering Java Interview Questions

  • Lead with the “why.” Don’t just say what something does — explain the design decision behind it.
  • Use concrete examples. Saying “immutability helps with thread safety” lands better if you sketch a two-sentence example.
  • Acknowledge trade-offs. Every Java feature has a cost. Mentioning them shows senior-level thinking.
  • Know which Java version introduced a feature. Saying “records were added in Java 16” signals that you follow the ecosystem.

In This Section


Last updated June 13, 2026
Was this helpful?