[{"data":1,"prerenderedAt":174},["ShallowReactive",2],{"qa-\u002Fjava\u002Ffundamentals\u002Fdata-types-variables":3},{"page":4,"siblings":166,"blog":171},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":157,"seo":158,"seoDescription":159,"stem":160,"subtopic":161,"topic":162,"topicSlug":163,"updated":164,"__hash__":165},"qa\u002Fjava\u002Ffundamentals\u002Fdata-types-variables.md","Data Types Variables",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"easy","md","Java","java",{},true,1,"\u002Fjava\u002Ffundamentals\u002Fdata-types-variables",[23,27,31,36,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153],{"id":24,"difficulty":14,"q":25,"a":26},"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":28,"difficulty":14,"q":29,"a":30},"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":32,"difficulty":33,"q":34,"a":35},"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":37,"difficulty":38,"q":39,"a":40},"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":42,"difficulty":14,"q":43,"a":44},"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":46,"difficulty":33,"q":47,"a":48},"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":50,"difficulty":33,"q":51,"a":52},"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":54,"difficulty":33,"q":55,"a":56},"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":58,"difficulty":38,"q":59,"a":60},"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":62,"difficulty":14,"q":63,"a":64},"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":66,"difficulty":33,"q":67,"a":68},"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":70,"difficulty":33,"q":71,"a":72},"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":74,"difficulty":14,"q":75,"a":76},"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":78,"difficulty":33,"q":79,"a":80},"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":82,"difficulty":33,"q":83,"a":84},"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":86,"difficulty":33,"q":87,"a":88},"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":90,"difficulty":33,"q":91,"a":92},"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":94,"difficulty":14,"q":95,"a":96},"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":98,"difficulty":14,"q":99,"a":100},"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":102,"difficulty":14,"q":103,"a":104},"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":106,"difficulty":33,"q":107,"a":108},"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":110,"difficulty":33,"q":111,"a":112},"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":114,"difficulty":14,"q":115,"a":116},"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":118,"difficulty":33,"q":119,"a":120},"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":122,"difficulty":14,"q":123,"a":124},"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":126,"difficulty":33,"q":127,"a":128},"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":130,"difficulty":14,"q":131,"a":132},"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":134,"difficulty":14,"q":135,"a":136},"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":138,"difficulty":33,"q":139,"a":140},"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":142,"difficulty":14,"q":143,"a":144},"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":146,"difficulty":14,"q":147,"a":148},"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":150,"difficulty":14,"q":151,"a":152},"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":154,"difficulty":14,"q":155,"a":156},"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":11},"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","Fundamentals","fundamentals","2026-06-18","_N5UicxRw1mn1pojTIjQziRqx6EuAJ7Vz7sfDiCpglY",[167,168],{"subtopic":161,"path":21,"order":20},{"subtopic":169,"path":170,"order":12},"Object-Oriented Programming","\u002Fjava\u002Ffundamentals\u002Foop",{"path":172,"title":173},"\u002Fblog\u002Fjava-data-types-variables","Java Data Types & Variables — Primitives, Wrappers & the String Pool",1781808676657]