CodeGym /Courses /JAVA 25 SELF /Common pitfalls of the new features

Common pitfalls of the new features

JAVA 25 SELF
Level 65 , Lesson 4
Available

1. Mistakes with the scope of pattern variables

One of the most common mistakes is trying to use a variable declared in a pattern (for example, String s in instanceof String s) outside the scope where it is valid.

Example

Object obj = "Hello, Java!";
if (obj instanceof String s) {
    System.out.println(s.length());
}
// Error! s is not visible here
System.out.println(s); // The compiler complains: cannot find symbol

Why is that?
A pattern variable (s in our case) exists only inside the block where the condition is true. This protects you from accidentally using the variable when it is not defined (for example, if obj is not a string).

Analogy
It’s like borrowing your friend’s car keys — but only while you’re in the garage. Step out of the garage and the keys automatically disappear :)

2. Mistakes with null

In pattern matching with instanceof there’s a quirky behavior: if the object is null, the result is always false, and the pattern variable is not created.

Example

Object obj = null;
if (obj instanceof String s) {
    // This block will never execute!
    System.out.println("This is a string: " + s);
}

Why?
Because null is not an instance of any type (not even Object). This can be confusing if you hoped to catch null via pattern matching.

How to do it correctly?

if (obj == null) {
    System.out.println("This is null!");
} else if (obj instanceof String s) {
    System.out.println("This is a string: " + s);
}

In pattern matching for switch (Java 21+) you can even add a dedicated branch for null:

switch (obj) {
    case String s -> System.out.println("String: " + s);
    case null -> System.out.println("This is null!");
    default -> System.out.println("Something else");
}

3. Mistakes with sealed classes

Sealed classes are a great way to restrict an inheritance hierarchy. But there are two characteristic mistakes:

Not all subclasses are listed in permits

When you declare a sealed class, you must explicitly list all direct subclasses via permits. If you forget one, the compiler will complain right away:

public sealed class Shape permits Circle, Rectangle { ... }

public final class Circle extends Shape { ... }
public final class Square extends Shape { ... } // Error! Square is not listed in permits

Solution:
Add all required subclasses to permits:

public sealed class Shape permits Circle, Rectangle, Square { ... }

Missing default in a switch over a non-sealed hierarchy

If you make a switch over a type that is not a sealed class (or is sealed but not all cases are covered), the compiler will require a default branch. If you forget it — you’ll get an error.

switch (shape) {
    case Circle c -> ...
    case Rectangle r -> ...
    // default is missing! If there are more variants, it's a compilation error
}

Best practice:
If you are sure you’ve handled all cases (for example, with a sealed class), you can omit default. If not, make sure to add default so you don’t miss unexpected types.

4. Mistakes with record patterns

Record patterns are very handy, but they work only with record classes. Attempting to use a record pattern for a regular class will lead to a compilation error.

Using record patterns for non-record classes

class Point { int x, y; }
Object obj = new Point();
// Error! Point is not a record
if (obj instanceof Point(int x, int y)) { ... }

Solution:
Use record patterns only for classes declared with record:

record Point(int x, int y) {}

Mismatched number or types of components

record Point(int x, int y) {}
Object obj = new Point(1, 2);

// Error: three variables specified, but Point has only two components
if (obj instanceof Point(int x, int y, int z)) { ... }
if (obj instanceof Point(String x, String y)) { ... } // Error: types do not match

5. Compatibility and support: old JDKs and IDEs

One of the most widespread mistakes is trying to use modern pattern matching features on older JDK versions or in IDEs that don’t support them.

Example

if (obj instanceof String s) { ... }

And the JDK 11 compiler (or even 15) says:
error: illegal start of type

Why?
Pattern matching for instanceof appeared only in Java 16. Pattern matching in switch appeared in Java 17 (preview) and was finalized in Java 21+. Record patterns are in Java 21+.

How to avoid it?

  • Check your JDK version: java --version
  • Make sure your IDE (IntelliJ IDEA, Eclipse, VS Code) supports the corresponding Java version. Sometimes you need to explicitly set the language level in your project settings!
  • If you use Gradle/Maven — set the required source/target version.

6. Congratulations 🎉

You have completed all 65(!) levels of our advanced Java 25 course. You are incredibly awesome 😎.

The final stretch was especially challenging. You’ve learned everything — from the first lambdas and anonymous classes to virtual threads, structured concurrency, and language features that only recently didn’t exist in Java at all.

This is not just a course — it’s a true developer super marathon: dozens of new concepts, hundreds of code examples, thousands of lines of practice. If you’re reading these lines, it means you’re not just a student, but a trailblazer of the new Java era ☕⚡

You were among the first to master the most cutting-edge capabilities of Java 25, including:

  • pattern matching and record -patterns,
  • sealed -classes and their pitfalls,
  • Scoped Values and Virtual Threads ,
  • structured concurrency and modern approaches to multithreading.

Now you have not just knowledge, but the skills of a developer of the future that many practicing Java architects don’t yet possess. You can write code that not only works, but also scales, is readable, and conforms to the most modern standards of the Java community.

🚀 So feel free to call yourself a Java 25 Certified Survivor 😉
And from here — it only gets more interesting: you now have a foundation that lets you confidently step into the world of enterprise development, high-load systems, and cutting-edge technologies.

Respect from the entire course team!
You’ve handled a challenge that few can.
See you in future versions of Java 👋

1
Task
JAVA 25 SELF, level 65, lesson 4
Locked
Variable scope when analyzing data 📊
Variable scope when analyzing data 📊
1
Task
JAVA 25 SELF, level 65, lesson 4
Locked
Testing the geometry library: record pattern type checking 🧪
Testing the geometry library: record pattern type checking 🧪
1
Survey/quiz
New language features, level 65, lesson 4
Unavailable
New language features
New language features
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION