Java's Subtle Behaviors: 3 Surprising Edge Cases

#Java Is Not As Simple As We Think Today, I interviewed an experienced Java developer. The candidate was doing great — solid fundamentals, clear communication, and a good grasp of concepts. I was impressed. Then I decided to turn up the difficulty a notch with a few tricky questions. To my surprise, the candidate struggled — not because of a lack of skill, but because these are the kind of edge cases that slip out of daily practice. I still moved the candidate to the next round because overall knowledge and problem-solving ability matter more than gotcha questions. But it made me reflect on something important. Why do experienced developers miss these? As we grow into system design, architecture, and leadership roles, we naturally move away from low-level nuances. The basics become “assumed knowledge” that we rarely revisit — and that’s where the gaps quietly form. Here are the three questions I asked: Q1: Does finally ALWAYS execute? We’re taught that finally block always runs. But does it really? try { System.out.println("Inside try"); System.exit(0); } finally { System.out.println("Finally executed"); } Finally executed” never prints. System.exit() shuts down the JVM before finally gets a chance to run. The rule has exceptions. Q2: Does substring() always create a new String? We know runtime String operations create new objects on the heap. But what does this print? String str = "java"; String s = str.substring(0); System.out.println(str == s); // true or false? It prints true. When substring(0) covers the entire string, Java is smart enough to return the same reference instead of creating a new object. The optimization many developers don’t expect. Q3: Are two Integer objects with the same value always equal with ==? Integer a = 127; Integer b = 127; System.out.println(a == b); // true Integer x = 128; Integer y = 128; System.out.println(x == y); // false Surprised? Java caches Integer objects in the range -128 to 127. Within this range, == works because both variables point to the same cached object. Beyond 127, new objects are created on the heap, and == compares references — not values. This is why .equals() should always be your default for object comparison. The takeaway: Java is not a simple language. Even professionals with years of experience get tripped up by its subtle behaviors and exceptions to the rules. The language rewards curiosity and continuous learning — no matter how senior you are. Keep revisiting the fundamentals. They have more depth than you remember. #Java #SoftwareEngineering #Interviews #CoreJava #ContinuousLearning #JavaDeveloper #JavaIsNotEasy

The last one could be a problem if you don't handle. Great 👍

Like
Reply

This highlights an important point, experience doesn't replace revision.Fundamentals needs to be revisited regularly.

Like
Reply

I actually started java again from scratch to relearn basic and core so I was able to understand this questions though not exact reason but I vaguely knew answers.

Like
Reply

Those are really helpful set of questions, Thanks .

Like
Reply

Thanks for the information

Like
Reply

Thanks Deepak sharma for sharing this, really helpful!

See more comments

To view or add a comment, sign in

Explore content categories