[{"data":1,"prerenderedAt":332},["ShallowReactive",2],{"topic-java-fundamentals":3},{"framework":4,"topic":15,"subtopics":23},{"id":5,"description":6,"extension":7,"icon":8,"meta":9,"name":10,"order":11,"slug":8,"stem":12,"tier":13,"__hash__":14},"frameworks\u002Fframeworks\u002Fjava.yml","Java interview questions on language fundamentals, object-oriented design, the Collections Framework, exception handling and concurrency — a staple of backend and enterprise technical interviews.","yml","java",{},"Java",5,"frameworks\u002Fjava",1,"jcUKEcQDoMZrreMRtZYJIVpkQlB-varlzbuwmzLr7kc",{"id":16,"description":17,"extension":7,"frameworkSlug":8,"meta":18,"name":19,"order":13,"slug":20,"stem":21,"__hash__":22},"topics\u002Ftopics\u002Fjava-fundamentals.yml","Primitives and wrappers, the String pool, pass-by-value semantics and the object model — the language basics every Java interview starts with.",{},"Fundamentals","fundamentals","topics\u002Fjava-fundamentals","I9Cp0oY-rFDDQ4-iChg29zHL5qVFZP30ULk-xU61i5Y",[24,181],{"id":25,"title":26,"body":27,"description":31,"difficulty":34,"extension":35,"framework":10,"frameworkSlug":8,"meta":36,"navigation":37,"order":13,"path":38,"questions":39,"related":174,"seo":175,"seoDescription":176,"stem":177,"subtopic":178,"topic":19,"topicSlug":20,"updated":179,"__hash__":180},"qa\u002Fjava\u002Ffundamentals\u002Fdata-types-variables.md","Data Types Variables",{"type":28,"value":29,"toc":30},"minimark",[],{"title":31,"searchDepth":32,"depth":32,"links":33},"",2,[],"easy","md",{},true,"\u002Fjava\u002Ffundamentals\u002Fdata-types-variables",[40,44,48,53,58,62,66,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170],{"id":41,"difficulty":34,"q":42,"a":43},"primitives-list","What are the eight primitive types in Java?","Java has exactly **eight** primitives, each with a fixed size and no methods:\n\n| Type | Size | Range \u002F notes |\n| ---- | ---- | ------------- |\n| `byte` | 8-bit | −128…127 |\n| `short` | 16-bit | −32,768…32,767 |\n| `int` | 32-bit | ~±2.1 billion (default for integer literals) |\n| `long` | 64-bit | very large; literal suffix `L` |\n| `float` | 32-bit | IEEE-754, suffix `f` |\n| `double` | 64-bit | IEEE-754 (default for decimal literals) |\n| `char` | 16-bit | a single UTF-16 code unit, `0`…`65535` |\n| `boolean` | JVM-defined | `true` \u002F `false` |\n\nPrimitives hold their value **directly** (on the stack or inline in an\nobject), unlike objects which are accessed through references. Everything else\nin Java — `String`, arrays, your classes — is a reference type.\n",{"id":45,"difficulty":34,"q":46,"a":47},"primitive-vs-wrapper","What is the difference between a primitive and its wrapper class?","Every primitive has an **object wrapper** in `java.lang`: `int`->`Integer`,\n`double`->`Double`, `char`->`Character`, `boolean`->`Boolean`, etc. The primitive\nstores a raw value; the wrapper is a full **object** on the heap that *contains*\nthe value plus object overhead (header, identity, can be `null`).\n\n```java\nint a = 5;              \u002F\u002F raw value, can never be null\nInteger b = 5;          \u002F\u002F object reference, can be null\nInteger c = null;       \u002F\u002F legal; int x = c; would throw NullPointerException\n```\n\nYou need wrappers wherever Java requires an object: generics\n(`List\u003CInteger>`, never `List\u003Cint>`), collections, and nullable fields.\nPrimitives are faster and lighter, so prefer them for arithmetic and hot loops.\n",{"id":49,"difficulty":50,"q":51,"a":52},"autoboxing","medium","What are autoboxing and unboxing?","**Autoboxing** is the compiler automatically converting a primitive to its\nwrapper; **unboxing** is the reverse. It lets primitives and wrappers mix\nseamlessly — `Integer.valueOf(...)` \u002F `intValue()` calls are inserted for you.\n\n```java\nList\u003CInteger> nums = new ArrayList\u003C>();\nnums.add(5);            \u002F\u002F autobox: int 5 -> Integer.valueOf(5)\nint first = nums.get(0); \u002F\u002F unbox: Integer -> intValue()\n```\n\nThe hidden cost: unboxing a `null` wrapper throws **`NullPointerException`**,\nand boxing in a tight loop creates throwaway objects (GC pressure). A classic\ntrap is `Integer sum = 0; for (...) sum += x;` which boxes\u002Funboxes every\niteration — use a primitive `int` accumulator instead.\n",{"id":54,"difficulty":55,"q":56,"a":57},"integer-cache","hard","Why does == sometimes return true and sometimes false for equal Integer values?","Because `==` on wrappers compares **references**, and Java **caches** boxed\n`Integer` objects for the range **−128 to 127** (the `IntegerCache`). Values in\nthat range return the *same* cached object; values outside it create new\nobjects each time.\n\n```java\nInteger a = 127, b = 127;\nSystem.out.println(a == b);   \u002F\u002F true  — same cached object\n\nInteger c = 128, d = 128;\nSystem.out.println(c == d);   \u002F\u002F false — two distinct objects\nSystem.out.println(c.equals(d)); \u002F\u002F true — value comparison\n```\n\nThe lesson interviewers want: **always compare wrapper values with\n`.equals()`** (or unbox to primitives), never `==`. The cache exists because\nsmall integers are extremely common, so reusing them saves allocations.\n",{"id":59,"difficulty":34,"q":60,"a":61},"equals-vs-eqeq","What is the difference between == and .equals() in Java?","`==` compares **references** for objects (do both variables point to the *same*\nobject?) and raw **values** for primitives. `.equals()` is a method that\ncompares **logical equality** — what \"equal\" means is defined by the class.\n\n```java\nString a = new String(\"hi\");\nString b = new String(\"hi\");\na == b        \u002F\u002F false — two different objects\na.equals(b)   \u002F\u002F true  — same characters\n\nint x = 5, y = 5;\nx == y        \u002F\u002F true  — primitive value comparison\n```\n\n`Object.equals` defaults to `==` (reference identity), so a class must\n**override** `equals` to get meaningful value comparison — `String`,\n`Integer`, and the collections all do.\n",{"id":63,"difficulty":50,"q":64,"a":65},"string-immutable","Why are Strings immutable in Java?","A `String`'s internal character data is `final` and never changes after\nconstruction; any \"modification\" returns a **new** `String`. Immutability buys\nseveral things: **safe sharing** in the string pool, **thread safety** without\nlocks, usability as **hash keys** (the hash can be cached and never goes\nstale), and **security** (a path\u002FURL can't be mutated after a check).\n\n```java\nString s = \"hello\";\ns.concat(\" world\");      \u002F\u002F creates a new String, discarded here\nSystem.out.println(s);   \u002F\u002F \"hello\" — s itself is unchanged\ns = s.concat(\" world\");  \u002F\u002F reassign the reference to the new String\n```\n\nThe trade-off is that heavy string building creates garbage — which is exactly\nwhy `StringBuilder` exists.\n",{"id":67,"difficulty":50,"q":68,"a":69},"string-pool","What is the String pool (string interning)?","The string pool is a special area where the JVM stores **one shared copy** of\neach distinct string **literal**. Two identical literals refer to the same\npooled object, saving memory. Strings made with `new` are *not* pooled — they\ncreate a fresh heap object — unless you call `.intern()`.\n\n```java\nString a = \"hi\";          \u002F\u002F pooled\nString b = \"hi\";          \u002F\u002F same pooled object\nString c = new String(\"hi\"); \u002F\u002F new heap object, NOT pooled\na == b           \u002F\u002F true\na == c           \u002F\u002F false\na == c.intern()  \u002F\u002F true — intern() returns the pooled copy\n```\n\nThis is why beginners hit bugs comparing strings with `==`: literals seem to\nwork (same pooled object) but `new`\u002Fcomputed strings don't. Always use\n`.equals()`.\n",{"id":71,"difficulty":50,"q":72,"a":73},"stringbuilder","What is the difference between String, StringBuilder and StringBuffer?","- **`String`** — immutable; every concatenation allocates a new object. Fine\n  for a few fixed pieces, wasteful in loops.\n- **`StringBuilder`** — a **mutable**, resizable character buffer. Not\n  synchronized, so it's fast; the right default for building strings.\n- **`StringBuffer`** — same API as `StringBuilder` but **synchronized**\n  (thread-safe), hence slower. Rarely needed today.\n\n```java\n\u002F\u002F O(n²) garbage — a new String each iteration\nString r = \"\";\nfor (String p : parts) r += p;\n\n\u002F\u002F one buffer, amortized O(n)\nStringBuilder sb = new StringBuilder();\nfor (String p : parts) sb.append(p);\nString r2 = sb.toString();\n```\n\nNote the compiler optimizes simple `a + b + c` into `StringBuilder` calls — the\nproblem is concatenation **inside loops**, where it can't.\n",{"id":75,"difficulty":55,"q":76,"a":77},"pass-by-value","Is Java pass-by-value or pass-by-reference?","Java is **always pass-by-value** — no exceptions. The subtlety is that for\nobjects, the *value being copied is the reference* (the pointer), not the\nobject. So a method can **mutate** the object the reference points to, but\n**reassigning** the parameter doesn't affect the caller's variable.\n\n```java\nvoid mutate(int[] arr) { arr[0] = 99; }   \u002F\u002F changes the caller's array\nvoid reassign(int[] arr) { arr = new int[]{0}; } \u002F\u002F no effect on caller\n\nint[] a = {1};\nmutate(a);    \u002F\u002F a is now {99}\nreassign(a);  \u002F\u002F a is still {99} — the copied reference was replaced locally\n```\n\nSay it crisply in an interview: \"Java passes references **by value**.\" The\nreference is copied; both copies point at the same object until one is\nreassigned.\n",{"id":79,"difficulty":34,"q":80,"a":81},"default-values","What are the default values of fields in Java?","**Instance and static fields** are automatically initialized to a zero value:\n`0` for numeric primitives, `false` for `boolean`, `\\u0000` (the null character) for `char`, and\n**`null`** for any reference type.\n\n```java\nclass Box {\n  int n;        \u002F\u002F 0\n  boolean ok;   \u002F\u002F false\n  String name;  \u002F\u002F null\n}\n```\n\nThe crucial exception: **local variables get no default**. The compiler\n*requires* you to assign one before use, or it's a compile error (\"variable\nmight not have been initialized\") — a deliberate guard against reading garbage.\n",{"id":83,"difficulty":50,"q":84,"a":85},"int-overflow","What happens on integer overflow in Java?","Integer arithmetic **wraps around silently** using two's-complement — no\nexception is thrown. Exceeding `Integer.MAX_VALUE` rolls over to\n`Integer.MIN_VALUE`.\n\n```java\nint max = Integer.MAX_VALUE;   \u002F\u002F 2_147_483_647\nSystem.out.println(max + 1);   \u002F\u002F -2147483648  (wraps, no error)\n\n\u002F\u002F common bug: this overflows before being assigned to long\nlong bad = 1_000_000 * 1_000_000;        \u002F\u002F -727379968\nlong good = 1_000_000L * 1_000_000;      \u002F\u002F 1000000000000 (promote first)\n```\n\nMitigations: promote to `long`, use `Math.addExact`\u002F`multiplyExact` (which\n*throw* `ArithmeticException` on overflow), or `BigInteger` for unbounded math.\n",{"id":87,"difficulty":50,"q":88,"a":89},"float-precision","Why is 0.1 + 0.2 not exactly 0.3 in Java?","`float` and `double` are **binary IEEE-754** floating point. Many decimal\nfractions (like `0.1`) have no exact binary representation, so they're stored\nas the nearest approximation and tiny errors accumulate.\n\n```java\nSystem.out.println(0.1 + 0.2);   \u002F\u002F 0.30000000000000004\nSystem.out.println(0.1 + 0.2 == 0.3); \u002F\u002F false\n```\n\nFor money or anything needing exact decimals, use **`BigDecimal`** (and\nconstruct it from a *String*, not a double):\n\n```java\nnew BigDecimal(\"0.1\").add(new BigDecimal(\"0.2\")); \u002F\u002F 0.3 exactly\n```\n\nNever compare floats with `==`; compare within a small epsilon instead.\n",{"id":91,"difficulty":34,"q":92,"a":93},"char-type","What is the char type and how does it relate to int?","`char` is a **16-bit unsigned** integer holding a single UTF-16 code unit\n(`'A'`, `'7'`, `'€'`). Because it's numeric under the hood, it participates in\narithmetic and auto-promotes to `int`.\n\n```java\nchar c = 'A';\nint code = c;            \u002F\u002F 65 (implicit widening)\nchar next = (char) (c + 1); \u002F\u002F 'B' (must cast back, since c+1 is int)\nSystem.out.println('a' + 'b'); \u002F\u002F 195, not \"ab\" — numeric addition!\n```\n\nA frequent gotcha: `'a' + 'b'` adds the code points, while `\"\" + 'a' + 'b'`\nconcatenates. Characters beyond the Basic Multilingual Plane (emoji) need two\nchars (a surrogate pair) or `int` code points.\n",{"id":95,"difficulty":50,"q":96,"a":97},"casting","What is the difference between widening and narrowing conversions?","**Widening** (smaller -> larger type, e.g. `int`->`long`->`double`) is safe and\n**implicit** — no data loss, no cast needed. **Narrowing** (larger -> smaller,\ne.g. `double`->`int`) can lose data, so it requires an **explicit cast** and you\naccept the truncation.\n\n```java\nint i = 100;\nlong l = i;          \u002F\u002F widening — automatic\ndouble d = i;        \u002F\u002F widening — automatic\n\ndouble pi = 3.99;\nint n = (int) pi;    \u002F\u002F narrowing — explicit; truncates to 3 (not rounded)\nbyte b = (byte) 300; \u002F\u002F narrowing — overflows to 44\n```\n\nNarrowing **truncates toward zero** for floating->integer (it doesn't round),\nand wraps for integer overflow — both common interview \"what prints?\" traps.\n",{"id":99,"difficulty":50,"q":100,"a":101},"var-keyword","What is the var keyword and what are its limits?","`var` (Java 10+) is **local variable type inference**: the compiler infers the\nstatic type from the initializer. It's still **statically typed** — `var` is\nnot a dynamic\u002F`Object` type — just less verbose.\n\n```java\nvar list = new ArrayList\u003CString>();  \u002F\u002F inferred ArrayList\u003CString>\nvar count = 10;                      \u002F\u002F int\nfor (var entry : map.entrySet()) { } \u002F\u002F inferred Map.Entry\u003C...>\n```\n\nRestrictions: only for **local variables with an initializer**. You **can't**\nuse `var` for fields, method parameters, return types, or without an\ninitializer (`var x;` is illegal), and `var x = null;` won't compile (no type\nto infer).\n",{"id":103,"difficulty":50,"q":104,"a":105},"final-keyword","What does the final keyword mean for variables?","A `final` variable can be **assigned only once**. For a primitive that fixes\nthe value; for a reference it fixes **which object** the variable points to —\nthe object itself can still be mutated.\n\n```java\nfinal int MAX = 10;     \u002F\u002F MAX = 11; would not compile\nfinal List\u003CString> xs = new ArrayList\u003C>();\nxs.add(\"ok\");           \u002F\u002F mutating the object is allowed\nxs = new ArrayList\u003C>(); \u002F\u002F reassigning the reference is not\n```\n\n`final` also applies to fields (must be set by the end of construction),\nmethod parameters, and is required for variables a lambda\u002Fanonymous class\ncaptures (they must be `final` or *effectively final*).\n",{"id":107,"difficulty":50,"q":108,"a":109},"static-vs-instance","What is the difference between static and instance variables?","A **static** (class) variable belongs to the **class** — there's exactly **one\ncopy** shared by all instances. An **instance** variable belongs to each\n**object** — every `new` gets its own copy.\n\n```java\nclass Counter {\n  static int total;   \u002F\u002F one shared across all Counters\n  int id;             \u002F\u002F one per instance\n  Counter() { id = ++total; }\n}\nnew Counter(); \u002F\u002F id=1, total=1\nnew Counter(); \u002F\u002F id=2, total=2  (total is shared)\n```\n\nAccess statics via the class name (`Counter.total`). Statics are initialized\nwhen the class is loaded and live for the program's lifetime, which is why\nmutable static state is a common source of bugs and memory leaks.\n",{"id":111,"difficulty":34,"q":112,"a":113},"literals","How do numeric literals and underscores work in Java?","Literals default to `int` (integers) and `double` (decimals); suffixes change\nthat: `L`\u002F`l` for `long`, `f`\u002F`F` for `float`, `d`\u002F`D` for `double`. You can\nalso write binary (`0b`), octal (`0`), and hex (`0x`) literals, and use\n**underscores** as digit separators for readability.\n\n```java\nlong big   = 10_000_000_000L;  \u002F\u002F L needed — exceeds int range\nfloat rate = 1.5f;\nint  mask  = 0xFF;             \u002F\u002F 255 in hex\nint  bits  = 0b1010;           \u002F\u002F 10 in binary\nint  million = 1_000_000;      \u002F\u002F underscores ignored by the compiler\n```\n\nForgetting the `L` on a large literal is a classic bug: `10_000_000_000` alone\nwon't compile because it overflows `int`.\n",{"id":115,"difficulty":34,"q":116,"a":117},"ternary","What is the ternary operator and a common pitfall with it?","The ternary `condition ? a : b` is an **expression** that evaluates to `a` when\nthe condition is true, else `b` — a compact `if\u002Felse` that returns a value.\n\n```java\nString label = (n % 2 == 0) ? \"even\" : \"odd\";\nint max = (a > b) ? a : b;\n```\n\nThe subtle trap is **type promotion \u002F unboxing** of the two branches: if one\nbranch is a primitive and the other a wrapper, the result is unboxed, so a\n`null` wrapper branch can throw `NullPointerException`:\n\n```java\nInteger x = null;\nObject o = true ? 0 : x;   \u002F\u002F fine\nint bad  = false ? 0 : x;  \u002F\u002F NPE — both branches unboxed to int\n```\n",{"id":119,"difficulty":34,"q":120,"a":121},"arrays-basics","How are arrays represented in Java?","An array is an **object** on the heap with a fixed length set at creation; the\nvariable holds a reference to it. Elements are stored contiguously and default\nto their zero value (`0`\u002F`false`\u002F`null`).\n\n```java\nint[] a = new int[3];        \u002F\u002F {0, 0, 0}\nint[] b = {1, 2, 3};         \u002F\u002F array initializer\nString[] names = new String[2]; \u002F\u002F {null, null}\nSystem.out.println(a.length);   \u002F\u002F 3 — a field, not a method\n```\n\nKey facts: `length` is a **field** (no parentheses), the size is **immutable**\nonce created (need a bigger array? allocate a new one or use `ArrayList`), and\nout-of-bounds access throws `ArrayIndexOutOfBoundsException`.\n",{"id":123,"difficulty":50,"q":124,"a":125},"multidim-arrays","How do multidimensional and jagged arrays work?","Java has no true 2D arrays — a `int[][]` is an **array of arrays**. That means\nrows can have different lengths (a **jagged** array), and each row is a separate\nheap object.\n\n```java\nint[][] grid = new int[2][3];   \u002F\u002F 2 rows, 3 cols each\ngrid[0][1] = 5;\n\nint[][] jagged = new int[2][];  \u002F\u002F rows allocated separately\njagged[0] = new int[]{1, 2};\njagged[1] = new int[]{3, 4, 5}; \u002F\u002F different length — legal\n```\n\nBecause rows are independent objects, iterating with `row.length` (not a fixed\ncolumn count) is the safe pattern.\n",{"id":127,"difficulty":50,"q":128,"a":129},"type-promotion","How does numeric promotion work in arithmetic expressions?","In arithmetic, operands smaller than `int` (`byte`, `short`, `char`) are first\n**promoted to `int`**, and if any operand is `long`\u002F`float`\u002F`double` the whole\nexpression is promoted to the widest type. This is why byte arithmetic returns\nan `int`.\n\n```java\nbyte a = 10, b = 20;\nbyte c = a + b;        \u002F\u002F won't compile — a + b is int\nbyte d = (byte)(a + b); \u002F\u002F cast back\n\nint i = 5;\ndouble e = i \u002F 2;      \u002F\u002F 2.0 — int division happens FIRST, then widens\ndouble f = i \u002F 2.0;    \u002F\u002F 2.5 — one double operand promotes the division\n```\n\nThe `5 \u002F 2 == 2` integer-division surprise is the most common version of this\nin interviews.\n",{"id":131,"difficulty":34,"q":132,"a":133},"null-keyword","What is null and what can and cannot be null in Java?","`null` is a special literal meaning a reference points to **no object**. Only\n**reference types** can be `null` — primitives cannot. Using a `null` reference\n(calling a method, accessing a field, unboxing) throws **`NullPointerException`**.\n\n```java\nString s = null;\ns.length();          \u002F\u002F NullPointerException\nint[] a = null;\nint n = a.length;    \u002F\u002F NPE\nInteger boxed = null;\nint x = boxed;       \u002F\u002F NPE — unboxing null\n```\n\n`null` is the same regardless of type, and `instanceof` on `null` is always\n`false`. Modern Java offers `Optional` and (Java 14+) **helpful NPE messages**\nthat name the exact variable that was null.\n",{"id":135,"difficulty":50,"q":136,"a":137},"object-class","What methods does every object inherit from Object?","Every class implicitly extends `java.lang.Object`, inheriting:\n\n- `equals(Object)` — logical equality (default: reference identity).\n- `hashCode()` — int hash, must be consistent with `equals`.\n- `toString()` — string form (default: `ClassName@hexHash`).\n- `getClass()` — runtime class object.\n- `clone()` — shallow copy (protected; needs `Cloneable`).\n- `wait()\u002Fnotify()\u002FnotifyAll()` — thread coordination on the object's monitor.\n- `finalize()` — deprecated cleanup hook.\n\n```java\nclass Point {\n  int x, y;\n  @Override public String toString() { return \"(\" + x + \",\" + y + \")\"; }\n}\n```\n\nYou'll most often override `equals`, `hashCode`, and `toString` — and the\nfirst two must be overridden **together** to honor their contract.\n",{"id":139,"difficulty":34,"q":140,"a":141},"scope-block","What is variable scope in Java?","A variable is visible only within the **block (`{ }`) it's declared in**, and\nceases to exist when that block ends. Inner blocks can see outer variables, but\nnot vice versa, and you can't redeclare a name that's already in scope.\n\n```java\nvoid m() {\n  int x = 1;\n  if (x > 0) {\n    int y = 2;        \u002F\u002F visible only inside this if\n    System.out.println(x + y);\n  }\n  \u002F\u002F y is out of scope here\n}\n```\n\nLoop variables (`for (int i ...)`) are scoped to the loop. Unlike fields, local\nvariables have **no default** and must be assigned before use.\n",{"id":143,"difficulty":50,"q":144,"a":145},"implicit-explicit-cast","When do you need an explicit cast for reference types?","Assigning a subclass reference to a superclass variable (**upcasting**) is\nimplicit and always safe. Going the other way (**downcasting**) needs an\nexplicit cast *and* is checked at runtime — a wrong cast throws\n`ClassCastException`.\n\n```java\nObject o = \"hello\";          \u002F\u002F upcast — implicit\nString s = (String) o;       \u002F\u002F downcast — explicit, succeeds\nInteger bad = (Integer) o;   \u002F\u002F compiles, but throws ClassCastException\n\nif (o instanceof String str) \u002F\u002F pattern matching (Java 16+) guards the cast\n    System.out.println(str.length());\n```\n\nGuard downcasts with `instanceof` (ideally the pattern form) to avoid runtime\nfailures.\n",{"id":147,"difficulty":34,"q":148,"a":149},"constants","How do you define a constant in Java?","The idiom is **`static final`** with an UPPER_SNAKE_CASE name. `static` means\none shared copy; `final` means it can't be reassigned. The compiler can inline\n`static final` primitive\u002F`String` constants for efficiency.\n\n```java\npublic class Config {\n  public static final int MAX_RETRIES = 3;\n  public static final String APP_NAME = \"Interviews\";\n}\n```\n\nNote `final` on a reference constant only freezes the reference, not the\nobject — `static final List\u003CString> X = new ArrayList\u003C>()` can still be mutated,\nso use `List.of(...)` or `Collections.unmodifiableList` for a truly constant\ncollection.\n",{"id":151,"difficulty":34,"q":152,"a":153},"wrapper-parsing","How do you convert between Strings and numbers?","Use the wrapper classes' static methods. `parseXxx` returns a **primitive**;\n`valueOf` returns a **wrapper object**. Going the other way, `String.valueOf`\nor concatenation produces text.\n\n```java\nint n      = Integer.parseInt(\"42\");     \u002F\u002F primitive int\nInteger w  = Integer.valueOf(\"42\");       \u002F\u002F Integer object\ndouble d   = Double.parseDouble(\"3.14\");\nString s   = String.valueOf(42);          \u002F\u002F \"42\"\nString s2  = \"\" + 42;                      \u002F\u002F \"42\" (concatenation)\n```\n\nA malformed string throws **`NumberFormatException`**, so wrap parsing of\nuntrusted input in a try\u002Fcatch or validate first.\n",{"id":155,"difficulty":50,"q":156,"a":157},"bitwise","What are the bitwise and shift operators in Java?","Java has `&` (AND), `|` (OR), `^` (XOR), `~` (NOT), and shifts `\u003C\u003C`, `>>`\n(signed\u002Farithmetic right shift), and `>>>` (unsigned\u002Flogical right shift, which\nfills with zeros).\n\n```java\n5 & 3    \u002F\u002F 1   (0101 & 0011)\n5 | 3    \u002F\u002F 7\n5 ^ 3    \u002F\u002F 6\n1 \u003C\u003C 4   \u002F\u002F 16  (multiply by 2^4)\n-8 >> 1  \u002F\u002F -4  (sign-preserving)\n-8 >>> 28 \u002F\u002F 15 (zero-filled — treats bits as unsigned)\n```\n\n`>>>` is unique to Java (no unsigned types) and is the trap: it's the only shift\nthat ignores the sign bit. Bitwise `&`\u002F`|` also work on `boolean` as\nnon-short-circuiting logical operators.\n",{"id":159,"difficulty":34,"q":160,"a":161},"enhanced-for","What is the enhanced for loop and its limitations?","The enhanced for (for-each) iterates any array or `Iterable` without an index,\nreading each element in turn.\n\n```java\nfor (String name : names) {\n  System.out.println(name);\n}\n```\n\nIts limits, often asked about: you **can't get the index**, you can't iterate\ntwo collections in lockstep, and you **can't modify the collection** during\niteration (it uses an iterator under the hood, so adding\u002Fremoving throws\n`ConcurrentModificationException`). Reassigning the loop variable also doesn't\nchange the underlying element — use a classic indexed `for` or an explicit\n`Iterator` for those cases.\n",{"id":163,"difficulty":34,"q":164,"a":165},"ternary-vs-if","What is the difference between an expression and a statement?","An **expression** evaluates to a value (`a + b`, `x > 0`, `obj.method()`); a\n**statement** is a complete instruction that performs an action (`if`, `for`,\nassignments, `return`). Expressions can be nested inside statements.\n\n```java\nint max = (a > b) ? a : b;   \u002F\u002F ternary is an EXPRESSION (has a value)\nif (a > b) { max = a; }      \u002F\u002F if is a STATEMENT (no value)\n```\n\nThis distinction explains why you can write `int x = a > b ? a : b;` but not\n`int x = if (...) ...;` — `if` produces no value. (Java's `switch` gained an\n*expression* form in Java 14 that does yield a value.)\n",{"id":167,"difficulty":34,"q":168,"a":169},"text-blocks","What are text blocks in Java?","Text blocks (Java 15+) are multi-line string literals delimited by triple\nquotes `\"\"\"`. They preserve line breaks and let you write JSON, SQL, or HTML\nwithout escaping quotes or concatenating lines.\n\n```java\nString json = \"\"\"\n    {\n      \"name\": \"Ada\",\n      \"role\": \"engineer\"\n    }\n    \"\"\";\n```\n\nIncidental leading whitespace is stripped based on the closing delimiter's\nindentation, and the result is just a normal `String` — so it still goes\nthrough the pool and supports all `String` methods.\n",{"id":171,"difficulty":34,"q":172,"a":173},"identifier-rules","What are the rules for valid Java identifiers?","An identifier may contain letters, digits, `_`, and `$`, but **can't start with\na digit**, can't be a **reserved keyword** (`class`, `int`, `for`…), and is\n**case-sensitive** (`count` ≠ `Count`). Unicode letters are allowed.\n\n```java\nint count, _total, $price, αβγ;  \u002F\u002F all legal\nint 2fast;   \u002F\u002F can't start with a digit\nint class;   \u002F\u002F reserved keyword\n```\n\nBy convention (not enforced): `camelCase` for variables\u002Fmethods,\n`PascalCase` for types, `UPPER_SNAKE_CASE` for constants, and `$` is left for\ngenerated code.\n",null,{"description":31},"Java data types and variables interview questions — primitives vs wrappers, autoboxing, Integer caching, String immutability and the pool, pass-by-value, casting and the var keyword.","java\u002Ffundamentals\u002Fdata-types-variables","Data Types & Variables","2026-06-18","_N5UicxRw1mn1pojTIjQziRqx6EuAJ7Vz7sfDiCpglY",{"id":182,"title":183,"body":184,"description":31,"difficulty":50,"extension":35,"framework":10,"frameworkSlug":8,"meta":188,"navigation":37,"order":32,"path":189,"questions":190,"related":174,"seo":327,"seoDescription":328,"stem":329,"subtopic":330,"topic":19,"topicSlug":20,"updated":179,"__hash__":331},"qa\u002Fjava\u002Ffundamentals\u002Foop.md","Oop",{"type":28,"value":185,"toc":186},[],{"title":31,"searchDepth":32,"depth":32,"links":187},[],{},"\u002Fjava\u002Ffundamentals\u002Foop",[191,195,199,203,207,211,215,219,223,227,231,235,239,243,247,251,255,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323],{"id":192,"difficulty":34,"q":193,"a":194},"four-pillars","What are the four pillars of object-oriented programming?","- **Encapsulation** — bundle data with the methods that operate on it and hide\n  internal state behind a public API (private fields + getters\u002Fsetters).\n- **Abstraction** — expose *what* an object does, hide *how*, via interfaces\n  and abstract classes.\n- **Inheritance** — a subclass reuses and extends a superclass's members\n  (`extends`).\n- **Polymorphism** — one reference type, many runtime forms; the actual\n  object's overridden method is called.\n\n```java\nclass Animal { String sound() { return \"...\"; } }\nclass Dog extends Animal { String sound() { return \"Woof\"; } } \u002F\u002F inheritance + override\nAnimal a = new Dog();   \u002F\u002F polymorphism\na.sound();              \u002F\u002F \"Woof\"\n```\n\nA good one-liner: encapsulation hides data, abstraction hides complexity,\ninheritance reuses behavior, polymorphism varies it.\n",{"id":196,"difficulty":34,"q":197,"a":198},"encapsulation","What is encapsulation and why does it matter?","Encapsulation means keeping fields **private** and exposing controlled access\nthrough methods, so an object protects its own invariants and you can change the\ninternals without breaking callers.\n\n```java\nclass Account {\n  private double balance;           \u002F\u002F hidden state\n  public void deposit(double amt) {\n    if (amt \u003C= 0) throw new IllegalArgumentException();\n    balance += amt;                 \u002F\u002F validated mutation\n  }\n  public double getBalance() { return balance; }\n}\n```\n\nBenefits: validation in one place, freedom to refactor representation, easier\ndebugging (state changes go through known methods), and thread-safety hooks. A\npublic mutable field gives up all of these.\n",{"id":200,"difficulty":34,"q":201,"a":202},"abstraction","What is abstraction and how is it achieved in Java?","Abstraction is exposing a **simplified contract** while hiding implementation\ndetail. In Java you achieve it with **interfaces** (pure contract) and\n**abstract classes** (partial implementation). Callers depend on the abstract\ntype, not the concrete class.\n\n```java\ninterface PaymentGateway { void charge(int cents); }\n\nclass StripeGateway implements PaymentGateway {\n  public void charge(int cents) { \u002F* API calls hidden here *\u002F }\n}\n\nPaymentGateway gw = new StripeGateway(); \u002F\u002F code depends only on the contract\n```\n\nThe payoff is decoupling: you can swap `StripeGateway` for `PayPalGateway`\nwithout touching the calling code — the basis of \"program to an interface.\"\n",{"id":204,"difficulty":34,"q":205,"a":206},"inheritance","What is inheritance and what does Java not allow?","Inheritance lets a subclass acquire the fields and methods of a superclass with\n`extends`, modeling an **is-a** relationship and enabling reuse + polymorphism.\n\n```java\nclass Vehicle { void start() { } }\nclass Car extends Vehicle { void honk() { } } \u002F\u002F Car is-a Vehicle\n```\n\nJava allows **single inheritance** of classes only — a class can extend exactly\none superclass (to avoid the \"diamond problem\"). It *can* implement **multiple\ninterfaces**, which is how Java gets multiple-type flexibility without\nmultiple class inheritance. `final` classes can't be extended at all.\n",{"id":208,"difficulty":50,"q":209,"a":210},"polymorphism","What is polymorphism and what are its forms?","Polymorphism = \"many forms.\" Java has two kinds:\n\n- **Runtime (dynamic) polymorphism** — method **overriding**. The JVM picks the\n  method based on the *actual object* at runtime (dynamic dispatch).\n- **Compile-time (static) polymorphism** — method **overloading**. The compiler\n  picks the method based on the *declared argument types*.\n\n```java\nAnimal a = new Dog();\na.sound();   \u002F\u002F runtime: Dog's override is chosen\n\nprint(5);    \u002F\u002F compile-time: print(int)\nprint(\"hi\"); \u002F\u002F compile-time: print(String)\n```\n\n\"Polymorphism\" in interviews usually means the runtime kind — the engine behind\n`List\u003CShape>` calling each shape's own `area()`.\n",{"id":212,"difficulty":50,"q":213,"a":214},"overloading-vs-overriding","What is the difference between overloading and overriding?","| | Overloading | Overriding |\n| --- | --- | --- |\n| What | Same name, **different parameters** | Subclass **replaces** a superclass method |\n| Signature | Must differ (type\u002Fcount) | Must be **identical** |\n| Bound | **Compile time** (static) | **Run time** (dynamic) |\n| Return type | Can differ | Same or covariant |\n\n```java\nclass Calc {\n  int add(int a, int b) { return a + b; }          \u002F\u002F overload 1\n  double add(double a, double b) { return a + b; }  \u002F\u002F overload 2\n}\nclass Base { void greet() { } }\nclass Sub extends Base { @Override void greet() { } } \u002F\u002F override\n```\n\nOverloading is about offering variations of an operation; overriding is about\nspecializing inherited behavior. Use `@Override` so the compiler verifies you\nactually overrode (and didn't accidentally overload).\n",{"id":216,"difficulty":50,"q":217,"a":218},"abstract-vs-interface","What is the difference between an abstract class and an interface?","- **Abstract class** — can have state (fields), constructors, and a mix of\n  concrete and abstract methods. A class extends **one**. Models an\n  *is-a* with shared implementation.\n- **Interface** — a contract; historically only abstract methods, now also\n  `default`\u002F`static`\u002F`private` methods, but **no instance state** (only\n  `public static final` constants). A class implements **many**.\n\n```java\nabstract class Shape {\n  private String name;            \u002F\u002F state allowed\n  abstract double area();         \u002F\u002F subclasses must implement\n  String describe() { return name + \": \" + area(); }\n}\ninterface Drawable { void draw(); default void hide() { } }\n```\n\nRule of thumb: use an **interface** for a capability multiple unrelated classes\ncan have (`Comparable`, `Runnable`); use an **abstract class** when subclasses\nshare state or implementation and form a tight family.\n",{"id":220,"difficulty":55,"q":221,"a":222},"inheritance-vs-composition","When should you favor composition over inheritance?","**Inheritance** (is-a) tightly couples a subclass to its parent's\nimplementation; changes to the base can silently break subclasses (the \"fragile\nbase class\" problem). **Composition** (has-a) builds behavior by *holding*\nother objects and delegating — looser coupling, more flexible.\n\n```java\n\u002F\u002F inheritance misused: a Stack is-a List? leaks all List methods\nclass Stack\u003CT> extends ArrayList\u003CT> { }\n\n\u002F\u002F composition: Stack HAS a list, exposes only stack operations\nclass Stack\u003CT> {\n  private final List\u003CT> items = new ArrayList\u003C>();\n  void push(T t) { items.add(t); }\n  T pop() { return items.remove(items.size() - 1); }\n}\n```\n\nGuideline (\"favor composition over inheritance\"): use inheritance only for a\ntrue is-a with a stable base designed for extension; otherwise compose. It also\nsidesteps single-inheritance limits.\n",{"id":224,"difficulty":50,"q":225,"a":226},"super-keyword","What does the super keyword do?","`super` refers to the **immediate superclass**. It does two jobs: call the\nparent **constructor** (`super(args)`, must be the first statement) and call an\n**overridden** parent method or access a parent field (`super.method()`).\n\n```java\nclass Animal {\n  Animal(String name) { }\n  void describe() { System.out.println(\"an animal\"); }\n}\nclass Dog extends Animal {\n  Dog(String name) {\n    super(name);              \u002F\u002F chain to parent constructor\n  }\n  @Override void describe() {\n    super.describe();         \u002F\u002F reuse parent behavior\n    System.out.println(\"...specifically a dog\");\n  }\n}\n```\n\nIf you don't call `super(...)` explicitly, the compiler inserts a no-arg\n`super()` — which fails to compile if the parent has no no-arg constructor.\n",{"id":228,"difficulty":34,"q":229,"a":230},"this-keyword","What does the this keyword refer to in Java?","`this` is a reference to the **current object**. Uses: disambiguate a field\nfrom a same-named parameter, call another constructor in the same class\n(`this(...)`, constructor chaining), and pass the current instance to other\nmethods.\n\n```java\nclass Point {\n  int x, y;\n  Point(int x, int y) {\n    this.x = x;          \u002F\u002F field vs parameter\n    this.y = y;\n  }\n  Point() { this(0, 0); } \u002F\u002F chain to the other constructor\n}\n```\n\n`this(...)` for constructor chaining, like `super(...)`, must be the first\nstatement — so you can't use both in one constructor.\n",{"id":232,"difficulty":34,"q":233,"a":234},"constructor","What is a constructor and what are its rules?","A constructor initializes a new object. It has the **class's name**, **no\nreturn type**, and runs when you use `new`. If you write none, the compiler\nsupplies a **default no-arg** constructor.\n\n```java\nclass User {\n  String name;\n  User() { this(\"anon\"); }      \u002F\u002F no-arg, chains\n  User(String name) { this.name = name; } \u002F\u002F parameterized\n}\n```\n\nRules interviewers probe: defining *any* constructor removes the free default\none; constructors can be overloaded; they're **not inherited** (but a subclass\nmust call one via `super`); and `private` constructors enable singletons and\nfactory-only construction.\n",{"id":236,"difficulty":50,"q":237,"a":238},"constructor-chaining","What is the order of execution when an object is constructed?","Construction runs **top-down** through the hierarchy:\n\n1. Static fields\u002Fblocks run **once** when the class first loads.\n2. On `new`: the superclass constructor runs first (via `super`), all the way\n   up to `Object`.\n3. Then instance field initializers and instance initializer blocks run.\n4. Then the rest of the subclass constructor body.\n\n```java\nclass A { A() { System.out.println(\"A ctor\"); } }\nclass B extends A {\n  int x = init();\n  int init() { System.out.println(\"B field\"); return 1; }\n  B() { System.out.println(\"B ctor\"); }\n}\n\u002F\u002F new B() prints: A ctor -> B field -> B ctor\n```\n\nA famous trap: calling an **overridable method from a constructor** runs the\nsubclass override *before* the subclass's fields are initialized — so it may see\n`null`\u002F`0`.\n",{"id":240,"difficulty":34,"q":241,"a":242},"access-modifiers","What are the four access modifiers in Java?","From most to least restrictive:\n\n- `private` — same class only.\n- *(default \u002F package-private)* — same package only (no keyword).\n- `protected` — same package **plus** subclasses (even in other packages).\n- `public` — everywhere.\n\n```java\npublic class Api {\n  private int secret;       \u002F\u002F class only\n  int packageScoped;        \u002F\u002F package\n  protected int forSubs;    \u002F\u002F package + subclasses\n  public int open;          \u002F\u002F everyone\n}\n```\n\nDefault the most restrictive that works (usually `private` fields) — it\nminimizes coupling. Note `protected` also grants package access, which surprises\npeople who think it's \"subclasses only.\"\n",{"id":244,"difficulty":50,"q":245,"a":246},"static-keyword","What does static mean for methods, fields and nested classes?","`static` binds a member to the **class** rather than an instance:\n\n- **static field** — one shared copy across all instances.\n- **static method** — called on the class, has **no `this`**, can't access\n  instance members directly (utility methods, factories).\n- **static nested class** — doesn't hold a reference to an outer instance.\n- **static block** — runs once at class load for static setup.\n\n```java\nclass MathUtil {\n  static final double PI = 3.14159;\n  static int square(int n) { return n * n; } \u002F\u002F MathUtil.square(5)\n}\n```\n\nBecause static methods aren't tied to an object, they **can't be overridden**\n(only *hidden*) and don't participate in runtime polymorphism.\n",{"id":248,"difficulty":50,"q":249,"a":250},"final-class-method","What does final mean for classes and methods?","- **`final` class** — cannot be extended (e.g. `String`, `Integer`). Locks the\n  design and lets the JIT optimize.\n- **`final` method** — cannot be overridden by subclasses; preserves critical\n  behavior.\n- **`final` field** — assign-once (constant once set).\n\n```java\nfinal class Constants { }          \u002F\u002F no subclassing\nclass Base {\n  final void critical() { }        \u002F\u002F subclasses can't override\n}\n```\n\nCommon reasons: immutability (a class meant to be immutable is often `final`),\nsecurity\u002Finvariant protection, and clarity of intent. It's the opposite of\n\"open for extension,\" so use it deliberately.\n",{"id":252,"difficulty":55,"q":253,"a":254},"equals-hashcode","What is the equals\u002FhashCode contract?","If you override `equals`, you **must** override `hashCode`, obeying:\n\n1. Equal objects (`a.equals(b)`) **must** have equal hash codes.\n2. `equals` must be reflexive, symmetric, transitive, and consistent.\n3. Unequal objects *may* share a hash code (collisions are allowed).\n\n```java\nclass Point {\n  final int x, y;\n  @Override public boolean equals(Object o) {\n    if (this == o) return true;\n    if (!(o instanceof Point p)) return false;\n    return x == p.x && y == p.y;\n  }\n  @Override public int hashCode() { return Objects.hash(x, y); }\n}\n```\n\nBreak the contract and **hash-based collections silently misbehave**: a\n`HashMap`\u002F`HashSet` may fail to find an object whose `hashCode` doesn't match\nits `equals`. Use `Objects.hash(...)` \u002F `Objects.equals(...)` to implement them.\n",{"id":256,"difficulty":34,"q":257,"a":258},"tostring","Why and how do you override toString?","The default `toString` returns `ClassName@hexHashCode` — useless in logs. Override\nit to return a readable representation, which is automatically used in string\nconcatenation, `println`, and debuggers.\n\n```java\nclass User {\n  String name; int age;\n  @Override public String toString() {\n    return \"User{name=\" + name + \", age=\" + age + \"}\";\n  }\n}\nSystem.out.println(new User()); \u002F\u002F User{name=null, age=0}\n```\n\nIt's purely for human-readable diagnostics — don't parse it programmatically.\nIDEs and `record`s can generate it for you.\n",{"id":260,"difficulty":50,"q":261,"a":262},"interface-default","What are default methods in interfaces and why were they added?","A **default method** provides a body inside an interface using the `default`\nkeyword. They were added in Java 8 so interfaces could **evolve** — e.g. adding\n`forEach` to `Iterable` — **without breaking** every existing implementer.\n\n```java\ninterface Greeter {\n  String name();\n  default String greet() { return \"Hello, \" + name(); } \u002F\u002F optional to override\n}\n```\n\nIf a class inherits conflicting defaults from two interfaces, it **must\noverride** to resolve the ambiguity (it can call `Iface.super.method()`).\nInterfaces can also have `static` and `private` helper methods now — but still\nno instance state.\n",{"id":264,"difficulty":50,"q":265,"a":266},"marker-interface","What is a marker interface?","A marker interface has **no methods** — it just *tags* a class so that code (or\nthe JVM) can detect a capability at runtime via `instanceof`. Classic examples:\n`Serializable`, `Cloneable`, `RandomAccess`.\n\n```java\nclass Config implements Serializable { } \u002F\u002F \"this class may be serialized\"\n```\n\nThe JVM checks `if (obj instanceof Serializable)` before serializing. Modern\nJava often prefers **annotations** for metadata, but marker interfaces still\ngive you compile-time type checking and `instanceof` support that annotations\ndon't.\n",{"id":268,"difficulty":50,"q":269,"a":270},"enum-basics","What are enums and what can they do beyond constants?","An `enum` defines a fixed set of named instances. Unlike `int` constants,\nenums are **type-safe**, can have **fields, constructors, and methods**, and\neach constant can even override behavior.\n\n```java\nenum Planet {\n  EARTH(9.81), MARS(3.71);\n  private final double gravity;\n  Planet(double g) { this.gravity = g; }   \u002F\u002F constructor\n  double weight(double mass) { return mass * gravity; }\n}\nPlanet.MARS.weight(70);  \u002F\u002F type-safe, behavior attached\n```\n\nEnums are implicitly `final` singletons (one instance per constant), work in\n`switch`, provide `values()`\u002F`valueOf()`\u002F`ordinal()`, and are the recommended\nway to implement singletons.\n",{"id":272,"difficulty":50,"q":273,"a":274},"record-class","What are records in Java?","A `record` (Java 16+) is a concise, **immutable** data carrier. From a one-line\ndeclaration the compiler generates a canonical constructor, `private final`\nfields, accessors, and `equals`\u002F`hashCode`\u002F`toString`.\n\n```java\nrecord Point(int x, int y) { }\n\nPoint p = new Point(1, 2);\np.x();                       \u002F\u002F accessor (no \"get\" prefix)\np.equals(new Point(1, 2));   \u002F\u002F true — value-based\n```\n\nThey're for transparent data aggregates (DTOs, value objects). Limits: records\nare `final`, can't extend a class (they implicitly extend `Record`), and all\nstate is in the header — you can still add a **compact constructor** for\nvalidation.\n",{"id":276,"difficulty":55,"q":277,"a":278},"nested-classes","What are the types of nested classes in Java?","- **Static nested class** — declared `static`; no link to an outer instance, a\n  namespaced helper.\n- **Inner (non-static) class** — holds an implicit reference to its enclosing\n  instance; can access its outer fields.\n- **Local class** — declared inside a method.\n- **Anonymous class** — an unnamed inner class created and instantiated at once.\n\n```java\nclass Outer {\n  static class Helper { }            \u002F\u002F static nested\n  class Inner { }                    \u002F\u002F inner — needs an Outer instance\n  Runnable r = new Runnable() {      \u002F\u002F anonymous\n    public void run() { }\n  };\n}\n```\n\nGotcha: a non-static inner class keeps the outer object alive (potential memory\nleak), so prefer `static` nested classes unless you actually need the enclosing\ninstance.\n",{"id":280,"difficulty":50,"q":281,"a":282},"object-equality-identity","What is the difference between identity, equality and equivalence?","- **Identity** — `a == b`: are they the *same object* in memory?\n- **Equality** — `a.equals(b)`: are they *logically the same value*, per the\n  class's definition?\n- Some classes also expose **ordering equivalence** via `compareTo == 0`.\n\n```java\nString a = new String(\"x\"), b = new String(\"x\");\na == b;            \u002F\u002F false (identity)\na.equals(b);       \u002F\u002F true  (equality)\n\nBigDecimal x = new BigDecimal(\"1.0\"), y = new BigDecimal(\"1.00\");\nx.equals(y);       \u002F\u002F false! (scale differs)\nx.compareTo(y) == 0; \u002F\u002F true  (numeric equivalence)\n```\n\n`BigDecimal` is the classic gotcha where `equals` and `compareTo` disagree.\n",{"id":284,"difficulty":55,"q":285,"a":286},"covariant-return","What is a covariant return type?","When overriding, the subclass method may return a **subtype** of the\nsuperclass method's return type — a covariant return. It lets overrides return\nmore specific types without a cast.\n\n```java\nclass Animal { Animal reproduce() { return new Animal(); } }\nclass Dog extends Animal {\n  @Override Dog reproduce() { return new Dog(); } \u002F\u002F narrower return — legal\n}\nDog puppy = new Dog().reproduce(); \u002F\u002F no cast needed\n```\n\nCommon in builder patterns and `clone()` overrides. (Parameters, by contrast,\nare *not* covariant — changing a parameter type makes it an overload, not an\noverride.)\n",{"id":288,"difficulty":55,"q":289,"a":290},"static-vs-dynamic-binding","What is the difference between static and dynamic binding?","**Static binding** is resolved by the compiler from the **declared type** —\nused for `static`, `private`, `final`, and overloaded methods, plus fields.\n**Dynamic binding** is resolved at runtime from the **actual object type** —\nused for overridden instance methods (virtual dispatch).\n\n```java\nclass A { static void s() { } void v() { } int f = 1; }\nclass B extends A { static void s() { } @Override void v() { } int f = 2; }\n\nA x = new B();\nx.v();   \u002F\u002F B.v()  — dynamic binding (overridden)\nx.s();   \u002F\u002F A.s()  — static binding (hidden, by declared type)\nx.f;     \u002F\u002F 1      — fields are static-bound, not polymorphic\n```\n\nKey insight: **fields and static methods are *hidden*, not overridden** — they\nbind to the declared type, which is a classic trick question.\n",{"id":292,"difficulty":55,"q":293,"a":294},"immutable-class","How do you design an immutable class?","Make the state impossible to change after construction:\n\n1. Mark the class `final` (no subclass can add mutability).\n2. Make all fields `private final`.\n3. Set everything in the constructor; provide **no setters**.\n4. **Defensively copy** mutable fields in and out (don't leak internal refs).\n\n```java\nfinal class Range {\n  private final int[] bounds;\n  Range(int[] bounds) { this.bounds = bounds.clone(); } \u002F\u002F copy in\n  int[] bounds() { return bounds.clone(); }             \u002F\u002F copy out\n}\n```\n\nImmutables are inherently **thread-safe**, cacheable, and safe as map keys —\n`String`, `Integer`, and `LocalDate` are all built this way.\n",{"id":296,"difficulty":50,"q":297,"a":298},"this-vs-super-ctor","Can a constructor call both this() and super()?","No. Both `this(...)` (chain to another constructor in the same class) and\n`super(...)` (chain to the parent) must be the **first statement** in a\nconstructor — and there can only be one first statement, so you use **at most\none** of them.\n\n```java\nclass Base { Base(int n) { } }\nclass Sub extends Base {\n  Sub() { this(5); }          \u002F\u002F delegates within Sub...\n  Sub(int n) { super(n); }    \u002F\u002F ...which then reaches super\n}\n```\n\nThe pattern is to funnel overloaded constructors through `this(...)` down to one\n\"primary\" constructor that finally calls `super(...)`.\n",{"id":300,"difficulty":50,"q":301,"a":302},"object-creation","What are the ways to create an object in Java?","- **`new`** — the normal path, invokes a constructor.\n- **Factory method** — e.g. `List.of()`, `Integer.valueOf()`, your own\n  `Builder.build()`.\n- **`Class.getDeclaredConstructor().newInstance()`** — reflection.\n- **`clone()`** — copy an existing object.\n- **Deserialization** — reconstruct from bytes (bypasses constructors).\n\n```java\nUser a = new User();                          \u002F\u002F new\nList\u003CInteger> b = List.of(1, 2);              \u002F\u002F factory\nUser c = User.class.getDeclaredConstructor().newInstance(); \u002F\u002F reflection\n```\n\nNote that reflection and deserialization can create objects **without running a\nconstructor**, which is why immutability\u002Fsingletons sometimes need extra guards.\n",{"id":304,"difficulty":34,"q":305,"a":306},"ducktyping-isa-hasa","What is the difference between an is-a and a has-a relationship?","- **is-a** -> inheritance. A `Car` *is a* `Vehicle` -> `class Car extends\n  Vehicle`.\n- **has-a** -> composition\u002Faggregation. A `Car` *has an* `Engine` -> the `Car`\n  holds an `Engine` field.\n\n```java\nclass Engine { }\nclass Car extends Vehicle {   \u002F\u002F is-a Vehicle\n  private final Engine engine = new Engine(); \u002F\u002F has-a Engine\n}\n```\n\nModeling tip: if you can't truthfully say \"X is a Y,\" don't use inheritance —\nreach for has-a (composition) instead. Misusing is-a (e.g. `Stack extends\nVector`) is a classic design smell.\n",{"id":308,"difficulty":55,"q":309,"a":310},"method-hiding","What is method hiding and how does it differ from overriding?","When a subclass declares a `static` method with the same signature as a parent\n`static` method, it **hides** rather than overrides it. The version called\ndepends on the **declared (compile-time) type**, not the runtime object — the\nopposite of overriding.\n\n```java\nclass A { static String who() { return \"A\"; } }\nclass B extends A { static String who() { return \"B\"; } }\n\nA ref = new B();\nref.who();   \u002F\u002F \"A\"  — static method, resolved by declared type (hiding)\n\u002F\u002F If who() were an instance method, this would be \"B\" (overriding)\n```\n\nBecause of this confusion, call static methods on the **class** (`A.who()`),\nnever through an instance reference.\n",{"id":312,"difficulty":50,"q":313,"a":314},"interface-vs-abstract-when","Can a class implement multiple interfaces with the same method?","Yes. If two interfaces declare the **same abstract** method, one implementation\nsatisfies both. But if they provide **conflicting `default`** methods, the class\n**must override** to break the tie, optionally delegating with\n`Interface.super.method()`.\n\n```java\ninterface A { default String hi() { return \"A\"; } }\ninterface B { default String hi() { return \"B\"; } }\n\nclass C implements A, B {\n  @Override public String hi() {\n    return A.super.hi();   \u002F\u002F explicitly choose A's default\n  }\n}\n```\n\nThis is Java's controlled answer to the multiple-inheritance \"diamond problem\":\nmultiple *types* are allowed, but conflicting *behavior* must be resolved\nexplicitly.\n",{"id":316,"difficulty":50,"q":317,"a":318},"polymorphism-collections","How does polymorphism enable programming to an interface?","By declaring variables and parameters as the **interface\u002Fsupertype**, your code\nworks with *any* implementation — the runtime calls the actual object's\nmethods. This decouples callers from concrete classes.\n\n```java\nvoid process(List\u003CString> items) { }   \u002F\u002F accepts ArrayList, LinkedList, List.of...\nList\u003CString> list = new ArrayList\u003C>();  \u002F\u002F swap impl freely\n\u002F\u002F list = new LinkedList\u003C>();           \u002F\u002F no caller changes needed\n```\n\n\"Program to an interface, not an implementation\" — depend on `List`, `Map`,\n`Collection`, not `ArrayList`\u002F`HashMap`. It makes code testable (inject fakes)\nand flexible (change implementations without ripple effects).\n",{"id":320,"difficulty":50,"q":321,"a":322},"cohesion-coupling","What are cohesion and coupling?","- **Cohesion** — how focused a class is on a single responsibility. **High\n  cohesion is good**: a `UserValidator` that only validates users.\n- **Coupling** — how dependent classes are on each other's internals. **Low\n  coupling is good**: classes interact through small, stable interfaces.\n\n```java\n\u002F\u002F low coupling: depends on an interface, not a concrete logger\nclass OrderService {\n  private final Logger log;            \u002F\u002F injected abstraction\n  OrderService(Logger log) { this.log = log; }\n}\n```\n\nThe goal of good OO design is **high cohesion, low coupling** — classes that do\none thing well and lean on each other as little as possible, which makes systems\neasier to change and test.\n",{"id":324,"difficulty":55,"q":325,"a":326},"solid","What do the SOLID principles stand for?","Five OO design principles for maintainable code:\n\n- **S** — Single Responsibility: a class has one reason to change.\n- **O** — Open\u002FClosed: open for extension, closed for modification.\n- **L** — Liskov Substitution: subtypes must be usable wherever their base is.\n- **I** — Interface Segregation: prefer small, specific interfaces over fat ones.\n- **D** — Dependency Inversion: depend on abstractions, not concretions.\n\n```java\n\u002F\u002F Dependency Inversion: high-level code depends on an interface\ninterface Repository { void save(Order o); }\nclass OrderService {\n  private final Repository repo;       \u002F\u002F not a concrete DB class\n  OrderService(Repository repo) { this.repo = repo; }\n}\n```\n\nLiskov is the one interviewers probe most: a subclass that throws on, or\nweakens, an inherited method (the `Square extends Rectangle` problem) violates\nit.\n",{"description":31},"Java OOP interview questions — the four pillars, inheritance vs composition, abstract classes vs interfaces, overloading vs overriding, polymorphism, the equals\u002FhashCode contract, records and enums.","java\u002Ffundamentals\u002Foop","Object-Oriented Programming","unDNeaf0bQsd2Gz0CAYtw3utDO8XyOVtZREhMpXE9oI",1781808674531]