Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
Chaturmind
← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 8+ Years (Senior & Lead)Expert Core Java
✓ FreeAdvanced· 11 min read

Tricky Java Output, Operators & OOP Edge Cases — Interview Questions

The "what does this print?" round for senior engineers — string concatenation order, numeric promotion, pre/post increment, string identity, division by zero, floating-point comparison, switch on null, variable scope — and OOP edge cases — private and static method "overriding", abstract + final, constructors with return types, constructor inheritance, return-type-only overloads, this() with super(), object slicing, and casting vs dynamic dispatch.

Published September 25, 2026


How to use this lesson

Senior interviews often open with rapid output-prediction questions. They aren't hard, but they test whether you reason from the language rules, rather than guessing. For each one:

  1. Say the answer.
  2. Name the rule behind it: left-to-right evaluation, binary numeric promotion, dynamic dispatch, static binding.

Naming the rule is what separates an 8-year answer from a lucky one.

Q1. What does System.out.println(10 + 20 + "Java" + 10 + 20); print?

Short answer: 30Java1020.

Key points to cover:

  • + is left-associative, and evaluated left to right.
  • 10 + 20 are both int, so this is numeric addition, giving 30.
  • 30 + "Java" has a String operand, so it becomes string concatenation: "30Java".
  • From then on, every + concatenates: "30Java" + 10 gives "30Java10", then "30Java1020".
  • To add the trailing numbers, use parentheses: ... + (10 + 20) prints 30Java30.

Learn it in depth → String Manipulation

Q2. Why does byte b = 10; b = b * 2; fail to compile?

Short answer: Because of binary numeric promotion. Arithmetic on byte, short and char operands is done in int, so b * 2 is an int. Assigning an int expression to a byte is a narrowing conversion, and needs an explicit cast.

byte b = 10;
b = (byte) (b * 2);   // explicit narrowing
b *= 2;               // compiles: compound assignment includes an implicit cast, (byte)(b * 2)
byte c = 10 * 2;      // compiles: constant expression that fits in a byte

Common trap: b *= 2 compiles, but overflows silently. byte x = 100; x *= 2; gives -56.

Q3. What does int a = 5; System.out.println(a++ + ++a); print?

Short answer: 12, and a ends up as 7.

Key points to cover:

  • Operands are evaluated left to right.
  • a++ yields the old value, 5, then sets a to 6.
  • ++a increments first, so a becomes 7, and it yields 7.
  • 5 + 7 = 12.
  • Code like this is legal Java, but unreadable. In a review, you'd split it into separate statements.

Q4. What does String s1 = "abc"; String s2 = new String("abc"); System.out.println(s1 == s2); print?

Short answer: false.

  • "abc" is a literal, interned in the string pool.
  • new String("abc") always creates a new heap object.
  • == compares references, so they differ.
  • s1.equals(s2) is true, and s1 == s2.intern() is true.

Q5. What happens if you divide an integer by zero? What about a double?

Short answer:

  • Integer division or remainder by zero (5 / 0, 5 % 0) throws ArithmeticException: / by zero.
  • Floating-point division follows IEEE 754, and never throws:
    • 5.0 / 0 gives Infinity;
    • -5.0 / 0 gives -Infinity;
    • 0.0 / 0 gives NaN;
    • 5 % 0.0 gives NaN.

Key points to cover:

  • A mixed expression is promoted to double first, so 5 / 0.0 gives Infinity, with no exception.
  • NaN != NaN is true. Use Double.isNaN(x).
  • Math.floorDiv/floorMod also throw for a zero int divisor.

Q6. What does System.out.println("Result: " + 2 + 3 * 4); print?

Short answer: Result: 212.

  • * has higher precedence than +, so 3 * 4 = 12 is computed first.
  • Then, left to right: "Result: " + 2 gives "Result: 2", then + 12 gives "Result: 212".

To print Result: 14, write "Result: " + (2 + 3 * 4).

Q7. Can you declare a local variable inside a loop and use it outside?

Short answer: No. A local variable's scope is the block where it's declared: the loop body, or the for header for the loop variable. Referencing it after the loop is a compile error ("cannot find symbol"). Declare it before the loop if you need the value afterwards.

int lastIndex = -1;
for (int i = 0; i < items.size(); i++) {
    String item = items.get(i);          // scope: this iteration's body
    if (item.isBlank()) lastIndex = i;
}
// item and i are not accessible here; lastIndex is

Key points to cover:

  • Each iteration gets a fresh variable. That's why variables declared in the body are effectively final per iteration, and can be captured by lambdas, while the classic for loop variable i can't be.

Q8. Why is it bad to compare floating-point values with ==?

Short answer: Most decimal fractions can't be represented exactly in binary, so arithmetic accumulates rounding error: 0.1 + 0.2 == 0.3 is false (the sum is 0.30000000000000004). There are also special cases:

  • NaN == NaN is false.
  • 0.0 == -0.0 is true, but Double.valueOf(0.0).equals(-0.0) is false.

What to do instead:

  • Compare with a tolerance: Math.abs(a - b) <= 1e-9, or relative to magnitude, or a few Math.ulp units.
  • Use BigDecimal for money, compared with compareTo. equals also compares the scale, so 2.0 isn't equal to 2.00.
  • Use Double.compare for sorting.
static boolean nearlyEqual(double a, double b, double relTol) {
    return Math.abs(a - b) <= relTol * Math.max(Math.abs(a), Math.abs(b));
}
new BigDecimal("0.1").add(new BigDecimal("0.2")).compareTo(new BigDecimal("0.3")) == 0;   // true

Common trap: new BigDecimal(0.1) captures the inexact binary value. Use BigDecimal.valueOf(0.1), or the String constructor.

Q9. What happens when a switch receives null?

Short answer: A classic switch on a String, an enum or a boxed type throws NullPointerException when the selector is null. It calls hashCode(), ordinal() or unboxes the value, and the default branch doesn't catch it.

Since Java 21, pattern-matching switch can handle it explicitly, with case null:

String label = switch (status) {          // status may be null
    case null -> "unknown";
    case "A", "ACTIVE" -> "active";
    default -> "other";
};

Before Java 21, guard with if (x == null), or Objects.requireNonNullElse(x, "").

Q10. Can a private method be overridden?

Short answer: No. Private methods aren't inherited, so a subclass method with the same signature is a completely separate method. Calls to it from inside the superclass always run the superclass's private version. There's no dynamic dispatch, because private methods are bound at compile time (invokespecial, or a nestmate invokevirtual that still can't be overridden).

class Base {
    private String id() { return "base"; }
    String describe() { return id(); }          // always calls Base.id()
}
class Child extends Base {
    String id() { return "child"; }             // a new method; adding @Override here is a compile error
}
new Child().describe();                         // "base"

Key points to cover:

  • @Override catches this mistake at compile time. Always use it.

Q11. What does this print? class A { int m() { return 1; } } class B extends A { int m() { return 2; } } A obj = new B(); System.out.println(obj.m());

Short answer: 2. Instance methods use dynamic dispatch: the JVM chooses the implementation from the runtime class of the object (B), not from the declared reference type (A). The reference type only decides which methods are visible at compile time.

Learn it in depth → Inheritance and Polymorphism

Q12. Can a class be both abstract and final?

Short answer: No, it's a compile error: "illegal combination of modifiers". abstract means "must be subclassed to be used", and final means "can't be subclassed". The same goes for an abstract final method.

Key points to cover:

  • If you want a type that is closed to unknown subclasses but still abstract, use a sealed class or interface (Java 17). For example, sealed abstract class Shape permits Circle, Square.
  • For a non-instantiable utility class, use a final class with a private constructor.

Q13. What if a constructor has a return type?

Short answer: Then it isn't a constructor. It's an ordinary method that happens to have the class's name. It compiles (IDEs warn you), but new MyClass() uses the default constructor, so your "initialisation" code never runs. That's a classic silent bug.

class Account {
    int balance;
    void Account() { balance = 100; }   // a method, not a constructor!
}
new Account().balance;                   // 0

Q14. Are constructors inherited?

Short answer: No. Constructors are not members, so they aren't inherited, and they can't be overridden. A subclass must declare its own constructors, and each one must call a superclass constructor:

  • explicitly, with super(args);
  • or implicitly: the compiler inserts super(), which fails to compile if the superclass has no accessible no-arg constructor.

Key points to cover:

  • Records, enums and Lombok (@RequiredArgsConstructor, @SuperBuilder) generate constructors. They don't inherit them either.

Q15. Can static methods be overridden?

Short answer: No, they're hidden, not overridden. A static method with the same signature in a subclass hides the parent's method. The call is resolved at compile time, from the reference type, so there's no polymorphism.

class Parent { static String who() { return "parent"; } }
class Child extends Parent { static String who() { return "child"; } }

Parent p = new Child();
p.who();          // "parent": uses the static type (and IDEs warn: call it as Parent.who())
Child.who();      // "child"

Key points to cover:

  • @Override on a static method is a compile error.
  • An instance method can't hide a static method, and a static method can't hide an instance method: both are compile errors.

Q16. What happens if two methods differ only in return type?

Short answer: It's a compile error: "method already defined". Java identifies a method by its name + parameter types (its signature). The return type isn't part of it, so the call m() would be ambiguous.

Key points to cover:

  • Overriding may change the return type only covariantly: a subtype of the original return type. For example, Animal create() can become Dog create() in a subclass.
  • Generic methods that erase to the same signature also clash ("name clash: same erasure"). For example, void f(List<String>) and void f(List<Integer>).

Q17. Can super() and this() both be used in the same constructor?

Short answer: No. An explicit constructor invocation, this(...) or super(...), must be the first statement, so there's room for only one. Constructor chaining solves this: this(...) delegates to another constructor, which eventually calls super(...).

class Order {
    Order(String id) { this(id, Instant.now()); }        // delegates
    Order(String id, Instant at) { super(); /* ... */ }   // the chain ends in super()
}

Key points to cover:

  • Since Java 25 (flexible constructor bodies, JEP 513), statements that don't touch this, such as argument validation, may appear before the super(...) or this(...) call. But there can still be only one explicit constructor call.

Q18. What's object slicing, and does it happen in Java?

Short answer: Object slicing is a C++ problem. Copying a derived object by value into a base-class variable copies only the base part, and the derived fields and overrides are "sliced off". Java doesn't slice: object variables hold references, so Base b = derived; copies the reference, and the object stays a complete Derived, with its overrides still active.

Key points to cover:

  • Java has slicing-like data loss when you explicitly convert objects:
    • mapping a subclass entity to a base DTO;
    • a base-class copy constructor;
    • Jackson serialisation of a declared base type without polymorphic type info (@JsonTypeInfo): the subclass fields disappear on deserialisation.

Q19. When a method is overridden and a reference is cast, which method runs?

Short answer: The overriding method of the actual object still runs. Casting a reference never changes the object, only the compile-time view. ((A) new B()).m() calls B.m(). What does depend on the static (cast) type:

  • fields: fields are hidden, not overridden;
  • static methods;
  • overload resolution, which is chosen at compile time from the argument types.
class A { String name = "A"; String m() { return "A.m"; } }
class B extends A { String name = "B"; String m() { return "B.m"; } }

B b = new B();
((A) b).m();      // "B.m": dynamic dispatch
((A) b).name;     // "A":   field access uses the static type

Key points to cover:

  • Casting to an incompatible type compiles if the types are related, but throws ClassCastException at runtime. Use instanceof pattern matching: if (a instanceof B bb).

Follow-up questions this topic invites — and their answers

Q: What does char c = 'A'; c += 1; System.out.println(c); print, and why does c = c + 1 fail? A: It prints B. c += 1 includes an implicit narrowing cast back to char. c = c + 1 produces an int, which needs an explicit (char) cast.

Q: What does Integer a = 127, b = 127; a == b give? And with 128? A: true for 127, because autoboxing uses Integer.valueOf, which caches −128..127. With 128 it's normally false: two different objects. Always compare boxed numbers with equals, or unbox first.

Q: What does Math.abs(Integer.MIN_VALUE) return? A: Integer.MIN_VALUE, which is still negative, because +2147483648 doesn't fit in an int. Use Math.absExact, which throws on overflow, or widen to long.

Q: What does System.out.println(1.0 / 0 == Double.POSITIVE_INFINITY); print? A: true. Floating-point division by zero gives infinity, and infinities compare equal to themselves (unlike NaN).

Next

Tricky Exceptions, Memory & Keyword Questions — Interview Questions

AI Tutor

Lesson: Tricky Java Output, Operators & OOP Edge Cases — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.