paint-brush
Is Migrating From Java 11 to Java 17 Worth It?by@sergeidzeboev
3,320 reads
3,320 reads

Is Migrating From Java 11 to Java 17 Worth It?

by Sergei DzeboevJuly 26th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Java 17 enhances coding with features like Text Blocks for multiline text, Records for data-safe classes, enhanced Switch Expressions, and Pattern Matching for instanceof. Sealed Classes offer restricted inheritance while improved NullPointerExceptions enable better error tracking, making Java 17 more efficient and user-friendly.
featured image - Is Migrating From Java 11 to Java 17 Worth It?
Sergei Dzeboev HackerNoon profile picture


Java version 17 brought some changes to Java but also made many developers reconsider their desire to move to other JVM languages. The most noticeable changes were made in the direction of modernizing the Java code and adding new language constructs to simplify it. Of course, the matter was not without changes to the Java core, which made Java even more efficient.

Text Blocks

The Text Block feature has finally appeared in Java. I am sure that this is one of the changes that Java programmers had been waiting for a very long time. Now, you can forget about long compound lines that are hard to read. Text blocks allow you to write multiline text in the most convenient way. Inside such a block, you can compose the text how you want to see it, and you can still use escape sequences for more precise formatting.


Java 11. String Escape Sequences:

    public String poem = "                " +
            "Twinkle, Twinkle, Little Star\n" +
            "                \n" +
            "                Twinkle, twinkle, little star,\n" +
            "                How I wonder what you are!\n" +
            "                Up above the world so high,\n" +
            "                Like a diamond in the sky.\n" +
            "                \n" +
            "                Twinkle, twinkle, little star,\n" +
            "                How I wonder what you are!";


Java 17. Text Block:

    public String poem = """
                Twinkle, Twinkle, Little Star
                
                Twinkle, twinkle, little star,
                How I wonder what you are!
                Up above the world so high,
                Like a diamond in the sky.
                
                Twinkle, twinkle, little star,
                How I wonder what you are!
            """;


Records

Another update that is slowly making the Java language more usable is Records. Previously, to create a class, we needed to describe the class, specify its fields, and add necessary methods such as equals, hashcode, getters, and setters. All of this has now become unnecessary since Records appeared. Records allow you to create data-safe classes by specifying only the required fields; all other methods will be created automatically. However, it is worth remembering that Records act as a data class and were created to store data, not to perform various actions. Records are thread-safe because all Record fields are final. The last important thing to know is that the generated method for getting the value of a field will not contain 'get' as it would in classic Java Beans.


Java 11. Data Class:

public class DataClass {
    public DataClass (Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    private final Integer id;
    private final String name;

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        ...
    }

    @Override
    public int hashCode() {
        ...
    }
}



Java 17. Record:

public record DataClass(Integer id, String name) {
}


The difference is obvious: while performing the same functions, creating Records requires significantly fewer lines of code.


New Switch Expressions

The list of changes also includes Switch Expressions. The changes affected not only the syntax of Switch Expressions, which made their writing more concise but also the functionality. Switch Expressions now return the result of an iteration, making it even easier to write code and make it even more concise. New Switch Expressions no longer require a break after each case.


Java 11. Switch Expression:

    public String getSeasonDescription(Season season) {
        String seasonDescription;
        switch (season) {
            case SPRING:
                seasonDescription = "Flowers are blooming!";
                break;
            case SUMMER:
                seasonDescription = "It's hot outside!";
                break;
            case AUTUMN:
                seasonDescription = "Leaves are falling!";
                break;
            case WINTER:
                seasonDescription = "Snow is coming!";
                break;
            default:
                throw new IllegalStateException("Invalid season: " + season);
        }
        return seasonDescription;
    }


Java 17. Enhanced Switch Expression:

    public String getSeasonDescription(Season season) {
        return switch (season) {
            case SPRING -> "Flowers are blooming!";
            case SUMMER -> "It's hot outside!";
            case AUTUMN -> "Leaves are falling!";
            case WINTER -> "Snow is coming!";
        };
    }


Pattern Matching For instanceof

Another design improvement has also affected the instanceof operator. Now, instanceof is safer and more concise. With this change, it is no longer necessary to first check if a given object is an instance of some class and then perform a cast; this can now be done in one line. As stated, this is not just syntactic sugar but rather a more optimized operator.


Java 11. Classic intanceof:

    public void findInstance(Object o) {
        if (o instanceof String) {
            String s = (String) o;
            System.out.printf("Object is a string %s", s);
        } else if (o instanceof Number) {
            Number n = (Number) o;
            System.out.printf("Object is a number %n", n);
        }
    }


Java 17. Updated intanceof

    public void findInstance(Object o) {
        if (o instanceof String s) {
            System.out.printf("Object is a string %s", s);
        } else if (o instanceof Number n) {
            System.out.printf("Object is a number %n", n);
        }
    }


Sealed Classes

Java 17 has also taken security into account and made a significant step in that direction. The idea was to restrict the inheritance of a class or interface while keeping it public. As a result, new types of classes, sealed classes, were added to Java. The syntax of a sealed class allows you to specify descendants that can use its functionality. In turn, inheritors can also allow or deny inheritance or specify classes that can be inherited along the chain. This feature allows you to be more flexible in creating a project and conveniently adjust the API of your code.


Java 17. Sealed class:

public sealed class SealedClass permits AnotherSealedClass, AnotherNonSealedClass, AnotherFinalClass {
}


Java 17. Non-sealed inheritor:

public non-sealed class AnotherNonSealedClass extends SealedClass {
}


Java 17. Final inheritor:

public final class AnotherFinalClass extends SealedClass {
}


Java 17. Sealed inheritor:

public sealed class AnotherSealedClass extends SealedClass permits AnotherNonSealedClassTwo {
}


Java 17. Non-sealed inheritor level two:

public non-sealed class AnotherNonSealedClassTwo extends AnotherSealedClass {
}


Helpful NullPointerExceptions

And finally, an incredibly useful update in Java 17 is the improved NullPointerException! Finally, in the stack trace logs, you can see which specific field caused the NullPointerException. This feature alone should encourage you to switch to Java 17. You no longer need to poke around in the code for a long time in search of that sinister place where the exception occurred; now Java will do everything for you.


Java 11. NPE:

    public static void main(String... args) {
        String s = null;
        System.out.println(s.toLowerCase());
    }


Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:4)


Java 17. Improved NPE:

    public static void main(String... args){
        String s = null;
        System.out.println(s.toLowerCase());
    }


Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because "s" is null
	at edu.javamodules/edu.javaversions.eleventoseventeen.NpeExample.main(NpeExample.java:7)


Other innovations

Of course, this is not the whole list of changes that have been made in Java 17, but discussed innovations are the most noticeable ones. As always, Java developers have done an excellent job in improving the JVM, making it even more efficient.



Verdict

All the improvements made in Java 17 convey one message: it's time to switch to this version. The transition promises a more concise syntax and improved performance. Your project will gain security, flexibility, and better error messages. If you have already migrated to Java 11, then moving to Java 17 will be smooth. Java's competitive advantage shines here as backward compatibility allows you to switch to Java 17 without any code changes and take advantage of all the updated features. Version 17 is a Long-term Support version, ensuring you receive all the necessary security updates for an extended period.