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: 2–5 Years

Revise the Fresher Tier

  • Revise: Core Java Fundamentals (Fresher Tier)
  • Revise: Collections, Threads, Java 8 & Coding (Fresher Tier)
  • Revise: Spring Core, Spring Boot & Spring MVC (Fresher Tier)
  • Revise: Hibernate, SQL, Microservices, Maven & Git (Fresher Tier)

Intermediate Core Java

  • Intermediate OOP & Language Features — Interview Questions
  • Enums, Generics, Pass-by-Value & Imports — Interview Questions
  • Collections Internals & Scenarios — Interview Questions
  • JVM, Memory & Class Loading — Interview Questions
  • Exception Design & Serialization Edge Cases — Interview Questions

Java 8 Deep Dive & Stream Coding

  • Lambdas, Functional Interfaces & Method References — Interview Questions
  • Default Methods, Backward Compatibility & Optional — Interview Questions
  • Stream API Internals (Part 1) — Interview Questions
  • Stream API Internals (Part 2) — Interview Questions
  • Stream Coding Problems (Level 2, Part 1) — Interview Questions
  • Stream Coding Problems (Level 2, Part 2) — Interview Questions

Concurrency & Multithreading

  • Synchronization, Locks & Deadlocks — Interview Questions
  • Executors, ThreadLocal & Concurrent Collections — Interview Questions

Spring Framework In Depth

  • Bean Lifecycle, Contexts & Circular Dependencies — Interview Questions
  • Spring Bean Conflicts, AOP, Batch & Injection Styles — Interview Questions

Spring Boot In Depth & Scenarios

  • Spring Boot Internals & Auto-Configuration — Interview Questions
  • Spring Boot Configuration, Profiles & Secrets — Interview Questions
  • Spring Boot Data, Transactions & Caching — Interview Questions
  • Spring Boot Testing, Error Pages & Deployment — Interview Questions
  • Spring Boot Performance, Scaling & Resilience — Interview Questions
  • Spring Boot Async, Events & Messaging — Interview Questions
  • Spring Boot Security Scenarios — Interview Questions
  • Actuator, AOP, Spring Cloud & Distributed Tracing — Interview Questions
  • External APIs, Files, GraphQL & WebFlux — Interview Questions

Spring Security

  • Spring Security — OAuth2, CORS, CSRF & Access Rules — Interview Questions
  • Spring Security — Passwords, Filter Chain, Sessions & Debugging — Interview Questions

Apache Kafka

  • Kafka Architecture, Topics & ZooKeeper vs KRaft — Interview Questions
  • Kafka Producers, Consumers, Reliability & Streams — Interview Questions
  • Kafka Security, Connect & Core Scenarios — Interview Questions
  • Kafka Production Scenarios — Interview Questions

Git, Maven & Gradle (Level II)

  • Git Workflows, Rebase & Conflict Handling — Interview Questions
  • Git Recovery, Hooks, Tags & Collaboration — Interview Questions
  • Maven Builds, Multi-Module Projects & Dependency Resolution — Interview Questions
  • Maven Profiles, settings.xml, Plugins & Quality Gates — Interview Questions
  • Gradle Fundamentals, Migration & Dependencies — Interview Questions
  • Gradle Performance, Plugins, Testing & Publishing — Interview Questions

Deployment & CI/CD

  • Sessions, CI/CD Pipelines, Rollbacks & Secrets — Interview Questions
  • Migrations, Zero-Downtime Releases, Containers & Monitoring — Interview Questions

JUnit 5 & Mockito

  • JUnit 5 — Interview Questions
  • Mockito Basics — Interview Questions
  • Mockito Advanced & Tricky Questions — Interview Questions
Chaturmind
← Java Interview Prep: 2–5 Years

Revise the Fresher Tier

  • Revise: Core Java Fundamentals (Fresher Tier)
  • Revise: Collections, Threads, Java 8 & Coding (Fresher Tier)
  • Revise: Spring Core, Spring Boot & Spring MVC (Fresher Tier)
  • Revise: Hibernate, SQL, Microservices, Maven & Git (Fresher Tier)

Intermediate Core Java

  • Intermediate OOP & Language Features — Interview Questions
  • Enums, Generics, Pass-by-Value & Imports — Interview Questions
  • Collections Internals & Scenarios — Interview Questions
  • JVM, Memory & Class Loading — Interview Questions
  • Exception Design & Serialization Edge Cases — Interview Questions

Java 8 Deep Dive & Stream Coding

  • Lambdas, Functional Interfaces & Method References — Interview Questions
  • Default Methods, Backward Compatibility & Optional — Interview Questions
  • Stream API Internals (Part 1) — Interview Questions
  • Stream API Internals (Part 2) — Interview Questions
  • Stream Coding Problems (Level 2, Part 1) — Interview Questions
  • Stream Coding Problems (Level 2, Part 2) — Interview Questions

Concurrency & Multithreading

  • Synchronization, Locks & Deadlocks — Interview Questions
  • Executors, ThreadLocal & Concurrent Collections — Interview Questions

Spring Framework In Depth

  • Bean Lifecycle, Contexts & Circular Dependencies — Interview Questions
  • Spring Bean Conflicts, AOP, Batch & Injection Styles — Interview Questions

Spring Boot In Depth & Scenarios

  • Spring Boot Internals & Auto-Configuration — Interview Questions
  • Spring Boot Configuration, Profiles & Secrets — Interview Questions
  • Spring Boot Data, Transactions & Caching — Interview Questions
  • Spring Boot Testing, Error Pages & Deployment — Interview Questions
  • Spring Boot Performance, Scaling & Resilience — Interview Questions
  • Spring Boot Async, Events & Messaging — Interview Questions
  • Spring Boot Security Scenarios — Interview Questions
  • Actuator, AOP, Spring Cloud & Distributed Tracing — Interview Questions
  • External APIs, Files, GraphQL & WebFlux — Interview Questions

Spring Security

  • Spring Security — OAuth2, CORS, CSRF & Access Rules — Interview Questions
  • Spring Security — Passwords, Filter Chain, Sessions & Debugging — Interview Questions

Apache Kafka

  • Kafka Architecture, Topics & ZooKeeper vs KRaft — Interview Questions
  • Kafka Producers, Consumers, Reliability & Streams — Interview Questions
  • Kafka Security, Connect & Core Scenarios — Interview Questions
  • Kafka Production Scenarios — Interview Questions

Git, Maven & Gradle (Level II)

  • Git Workflows, Rebase & Conflict Handling — Interview Questions
  • Git Recovery, Hooks, Tags & Collaboration — Interview Questions
  • Maven Builds, Multi-Module Projects & Dependency Resolution — Interview Questions
  • Maven Profiles, settings.xml, Plugins & Quality Gates — Interview Questions
  • Gradle Fundamentals, Migration & Dependencies — Interview Questions
  • Gradle Performance, Plugins, Testing & Publishing — Interview Questions

Deployment & CI/CD

  • Sessions, CI/CD Pipelines, Rollbacks & Secrets — Interview Questions
  • Migrations, Zero-Downtime Releases, Containers & Monitoring — Interview Questions

JUnit 5 & Mockito

  • JUnit 5 — Interview Questions
  • Mockito Basics — Interview Questions
  • Mockito Advanced & Tricky Questions — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 2–5 YearsIntermediate Core Java
✓ FreeIntermediate· 9 min read

Enums, Generics, Pass-by-Value & Imports — Interview Questions

Enums as real classes (and why they can't extend classes), iterating enums, the diamond operator, type inference, type erasure and why generic arrays are forbidden, pass-by-value explained with references, imports vs static imports, classes and objects in a real system, and this in static contexts.

Published September 25, 2026


How to use this lesson

These questions probe how well you understand what the compiler does for you: generics are erased, enums are generated classes, imports are compile-time only. Explaining the mechanism is what separates an intermediate answer from a fresher one.

Q1. What are enums, and why are they useful?

Short answer: An enum is a type with a fixed, type-safe set of instances. Under the hood it's a final class extending java.lang.Enum, with one public static final instance per constant. Enums replace "magic" int or String constants, so invalid values become impossible and switch statements can be checked for exhaustiveness.

public enum OrderStatus {
    PLACED { @Override boolean canCancel() { return true; } },
    SHIPPED { @Override boolean canCancel() { return false; } },
    DELIVERED { @Override boolean canCancel() { return false; } };

    abstract boolean canCancel();                        // behaviour per constant: no switch needed
}

Key points to cover:

  • Enums can have fields, constructors (always private), methods, per-constant bodies, and can implement interfaces.
  • They're singletons by construction, and safe with serialization and reflection. That's why an enum is the recommended singleton implementation.
  • Use EnumMap and EnumSet for very fast, compact enum-keyed collections.

Q2. Can an enum extend another class?

Short answer: No. Every enum already implicitly extends java.lang.Enum, and Java classes have only one superclass. Enums can implement interfaces, which is how you share behaviour, or make them pluggable.

interface PricingRule { BigDecimal apply(BigDecimal amount); }

enum Discount implements PricingRule {
    NONE    { public BigDecimal apply(BigDecimal a) { return a; } },
    FESTIVE { public BigDecimal apply(BigDecimal a) { return a.multiply(new BigDecimal("0.90")); } }
}

Key points to cover:

  • Enums also can't be extended: they're implicitly final. The constant-specific bodies are anonymous subclasses, created by the compiler.

Q3. Can an enum extend another class? (Asked again, often as a trick follow-up)

Short answer: The answer doesn't change: no, because java.lang.Enum is already its superclass. When interviewers repeat the question, they're usually checking the follow-up: "so how would you share code between enums?" Use a common interface with default methods, or delegate to a helper class that each enum holds as a field.

Q4. How do you iterate over all the values of an enum?

Short answer: Call the compiler-generated static values() method. It returns a new array of the constants, in declaration order.

for (OrderStatus s : OrderStatus.values()) {
    System.out.println(s.ordinal() + " " + s.name());
}
EnumSet.allOf(OrderStatus.class).forEach(System.out::println);       // no array copy
Arrays.stream(OrderStatus.values()).filter(OrderStatus::canCancel).toList();

Key points to cover:

  • values() clones the array on every call. In hot paths, cache it (private static final OrderStatus[] ALL = values();), or use EnumSet.allOf.

Q5. How do you iterate over enum values? (Same question, second phrasing)

Short answer: values() with a for-each loop, EnumSet.allOf(...), or a stream over values(). To look a constant up by name, use Enum.valueOf(Type.class, "NAME") or Type.valueOf("NAME"). It throws IllegalArgumentException for an unknown name, so validate external input before calling it.

Q6. What is the diamond operator?

Short answer: <> (Java 7) lets the compiler infer the generic type arguments of a constructor call from the context, so you don't repeat them: Map<String, List<Order>> byCustomer = new HashMap<>();.

Key points to cover:

  • Since Java 9, it also works with anonymous classes, as long as the inferred type is denotable.
  • Don't confuse it with the raw type: new ArrayList() (no <>) is a raw type, and loses type safety, with compiler warnings.

Q7. What is generic type inference?

Short answer: The compiler deduces the type arguments of generic methods and constructors from the arguments and the target type, so you rarely need to write them explicitly.

List<String> names = Collections.emptyList();          // T inferred as String from the target type
var map = Map.of("a", 1, "b", 2);                      // Map<String, Integer> inferred from the arguments
List<Integer> ids = Stream.of(3, 1, 2).sorted().toList();
Collections.<String>emptyList();                       // explicit type witness: rarely needed

Key points to cover:

  • Java 8 greatly improved target typing, especially for lambdas and chained generic calls.

Learn it in depth → Generics

Q8. What is type erasure?

Short answer: Generic type information exists only at compile time. The compiler checks the types, inserts the necessary casts, then erases the type parameters. List<String> and List<Integer> both become the raw List in bytecode, and T becomes its bound (Object, or Comparable for <T extends Comparable<T>>). This kept generics backward-compatible with pre-Java 5 code.

Consequences worth naming:

  • There's no new T(), no T.class, and no instanceof List<String>.
  • You can't overload m(List<String>) and m(List<Integer>), because they have the same erasure.
  • Heap pollution is possible with raw types and unchecked casts.
  • The compiler generates bridge methods to keep polymorphism working after erasure.
List<String> strings = new ArrayList<>();
List raw = strings;              // raw type: unchecked
raw.add(42);                     // compiles (with a warning)…
String s = strings.get(0);       // …ClassCastException HERE, far from the real bug

Key points to cover:

  • Some generic information does survive in class metadata: field types, method signatures and superclass declarations. That's how Jackson's TypeReference<List<Order>> and Spring's ResolvableType work.

Q9. Why can't you create an array of a generic type?

Short answer: Arrays are reified and covariant. They know their element type at runtime, and check every store (ArrayStoreException). Generics are erased, so the runtime couldn't check that an element really is a List<String>. Allowing new List<String>[10] would let wrong types slip in with no error at all, so the compiler forbids it.

// List<String>[] arr = new List<String>[10];          // compile error
List<?>[] ok = new List<?>[10];                        // unbounded wildcard arrays are allowed
List<List<String>> better = new ArrayList<>();         // prefer collections to arrays of generics

@SuppressWarnings("unchecked")
T[] items = (T[]) new Object[capacity];                // the common internal workaround (as ArrayList does)

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

Short answer: Always pass-by-value. For primitives, the value is copied. For objects, the reference is copied. So a method can mutate the object through its copy of the reference, but can't make the caller's variable point to a different object.

static void rename(Customer c) { c.setName("Ravi"); }        // mutates the shared object: the caller sees it
static void replace(Customer c) { c = new Customer("Meera"); } // reassigns the LOCAL copy: the caller doesn't see it

Customer x = new Customer("Asha");
rename(x);   // x.getName() → "Ravi"
replace(x);  // x.getName() → still "Ravi"

Common trap: "objects are passed by reference". If that were true, replace would change x. The classic proof is that you can't write a working swap(a, b) method for object references.

Q11. How do imports affect compilation and class loading?

Short answer: Imports are purely a compile-time convenience. They let you use simple names instead of fully qualified ones. They don't appear in the bytecode as instructions, don't load classes, and have no runtime cost. A class is loaded only when it's first actively used at runtime, whether or not it was imported.

Key points to cover:

  • Wildcard imports (java.util.*) don't import sub-packages, and aren't slower at runtime. Teams avoid them for readability, and to prevent ambiguity when a new class with the same name appears.
  • Unused imports are harmless at runtime, but linters flag them as clutter.

Q12. What's the difference between import and import static?

Short answer: import brings types into scope by simple name. import static brings a class's static members (methods and constants) into scope, so you can call max(a, b) instead of Math.max(a, b).

import static org.assertj.core.api.Assertions.assertThat;     // the typical, idiomatic use: test DSLs
import static java.util.concurrent.TimeUnit.SECONDS;

assertThat(order.total()).isEqualByComparingTo("499.00");
executor.awaitTermination(30, SECONDS);

Q13. How do static imports affect readability and maintainability?

Short answer: Used for well-known DSL-style APIs (AssertJ, Mockito, Hamcrest, Collectors.*, TimeUnit), they make code read naturally. Overused, they hide where a method comes from, clash with local names, and make code reviews harder. The guideline: static-import only widely recognised members, and avoid wildcard static imports in production code.

Q14. Give an example of how classes and objects interact in a real application.

Short answer: In an e-commerce checkout:

  • A Cart object holds CartItems.
  • CheckoutService (a Spring singleton) turns the cart into an Order, asks a PaymentGateway (interface → RazorpayGateway object) to charge it, saves the order through an OrderRepository, and publishes an OrderPlaced event that an EmailNotifier handles.
  • Each object owns its own state and behaviour, and they collaborate through interfaces, which keeps the design testable and extensible.
Order order = cart.toOrder(customer);                  // domain objects encapsulate the rules
PaymentResult result = paymentGateway.charge(order);   // collaborating through an interface
if (result.successful()) {
    orders.save(order.markPaid(result.reference()));
    events.publishEvent(new OrderPlaced(order.id()));
}

Learn it in depth → Object-Oriented Design Refresher

Q15. Can this be used in a static method or a static block?

Short answer: No. this refers to the current instance, and static methods and static initialisers run without one. They belong to the class, and run even when no object exists. Using this (or super) there is a compile error.

Key points to cover:

  • To reach instance state from a static context, take or create an instance explicitly: new App().run().

Follow-up questions this topic invites — and their answers

Q: What are bounded wildcards, and what is PECS? A: ? extends T means "some subtype of T": you can read Ts from it (a Producer). ? super T means "some supertype of T": you can write Ts into it (a Consumer). "Producer Extends, Consumer Super". For example, Collections.copy(List<? super T> dest, List<? extends T> src).

Q: Why is ordinal() dangerous to persist? A: Reordering or inserting enum constants changes their ordinals, silently corrupting stored data. Persist name() (JPA @Enumerated(EnumType.STRING)), or an explicit stable code field.

Q: What does var do, and is it dynamic typing? A: var (Java 10) is local variable type inference. The compiler infers a static type from the initialiser. The type is fixed at compile time, so it isn't dynamic typing.

Q: Can you get the actual type argument of a generic at runtime? A: Not from an instance (new ArrayList<String>() is just an ArrayList). But you can read it from declarations: a subclass (class OrderList extends ArrayList<Order>), fields and method signatures all keep it, through getGenericSuperclass() and friends.

Previous

Intermediate OOP & Language Features — Interview Questions

Next

Collections Internals & Scenarios — Interview Questions

AI Tutor

Lesson: Enums, Generics, Pass-by-Value & Imports — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.