← Java and object-oriented programming for interviews

Lesson 2 of 4

Core Java: strings, equality, exceptions and memory

2 min read

Strings

  • String is immutable: every "change" creates a new object. That makes strings safe to share and cache (the string pool), and safe as map keys.
  • "a" + "b" in a loop creates many objects; use StringBuilder (not thread-safe, fast) or StringBuffer (synchronized, slower).
  • == compares references; .equals() compares content. new String("hi") == "hi" is false.

equals and hashCode

If two objects are equals, they must have the same hashCode. Hash-based collections (HashMap, HashSet) use hashCode to find the bucket and equals to find the exact key. Override both together, or use a record:

java
public record Point(int x, int y) {}   // equals, hashCode, toString generated

If you override equals but not hashCode, two "equal" objects land in different buckets and set.contains(...) returns false.

Exceptions

text
Throwable
├── Error               (OutOfMemoryError, StackOverflowError: don't catch)
└── Exception
    ├── checked         (IOException, SQLException: must be caught or declared)
    └── RuntimeException (unchecked: NullPointerException, IllegalArgumentException,
                          ArrayIndexOutOfBoundsException)
java
try (BufferedReader r = Files.newBufferedReader(path)) {   // try-with-resources closes r
    return r.readLine();
} catch (IOException e) {
    throw new UncheckedIOException("Could not read " + path, e);   // keep the cause
} finally {
    log.debug("done");
}
  • throw raises an exception; throws declares one in a method signature.
  • final / finally / finalize is a classic trick question: a keyword, a block that always runs, and a deprecated GC hook.

Memory and the JVM

  • Stack: one per thread; method frames, local primitives and references. Freed automatically when a method returns.
  • Heap: all objects; shared by threads; cleaned by the garbage collector when objects are unreachable.
  • JDK (tools + JRE) → JRE (JVM + libraries) → JVM (runs bytecode). Java is "write once, run anywhere" because .java compiles to platform-independent .class bytecode, which the JVM interprets and JIT-compiles.
  • Java is pass-by-value always; for objects, the value passed is a copy of the reference. So a method can modify an object's fields but can't make the caller's variable point to a new object.

Wrapper classes and autoboxing

int ↔ Integer. Watch for NullPointerException when unboxing a null Integer, and for Integer caching: Integer a = 127, b = 127; a == b is true, but with 128 it's false. Use .equals.

Java 8+ features

Lambdas, functional interfaces, streams, Optional, the new date/time API (LocalDate), var (Java 10), records (16), switch expressions and text blocks.

java
Map<String, Long> byCity = students.stream()
    .filter(s -> s.gradYear() == 2026)
    .collect(Collectors.groupingBy(Student::city, Collectors.counting()));

Check yourself

  • Why is String immutable, and why does it matter for HashMap keys?
  • What breaks if you override equals without hashCode?
  • Checked vs unchecked exceptions: give two examples of each.

Sign up free to save your progress.

Core Java: strings, equality, exceptions and memory · Java and object-oriented programming for interviews · HireSol