Most times, I thought Java was making life harder. 😂
Coming from Python or C++, writing str.charAt(2) instead of str[2] felt completely unnecessary.
“Why can’t Java just let me index the string?”

Turns out, this wasn’t a random design choice. Java treats a String as an object, not just an array of characters. That one decision gives us things like:
- Immutable strings → Tokens, DB URLs, SQL queries, and other critical values can’t be modified accidentally.
- String pool → Identical strings share one object, saving memory.
- Cached hash codes → Faster
HashMaplookups because the hash is computed once and reused. - Thread safety → Multiple threads can safely read the same string without synchronization.
String a = "Java";
String b = "Java";
// Only one "Java" object is created.

Python and C++ make strings behave much more like character sequences. Neither approach is “better.” They’re optimizing for different things.
Good language design isn’t about making everything easier. It’s about choosing the right trade-offs. The more languages you learn, the more those trade-offs start making sense.