{"id":122140,"date":"2021-03-10T23:51:29","date_gmt":"2021-03-10T22:51:29","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=idea&#038;p=122140"},"modified":"2021-03-30T05:07:27","modified_gmt":"2021-03-30T04:07:27","slug":"java-16-and-intellij-idea","status":"publish","type":"idea","link":"https:\/\/blog.jetbrains.com\/pt-br\/idea\/2021\/03\/java-16-and-intellij-idea","title":{"rendered":"Java 16 and IntelliJ IDEA"},"content":{"rendered":"<p>If you are still working with Java 8, you might have mixed feelings about the news of the release of <a href=\"http:\/\/openjdk.java.net\/projects\/jdk\/16\/\" target=\"_blank\" rel=\"noopener\">Java 16<\/a>. However, you\u2019ll see these numbers are going to increment at a much faster and predictable rate with Java\u2019s six-month release cadence.<\/p>\n<p>I\u2019m personally excited about Java 16! It adds <a href=\"https:\/\/openjdk.java.net\/jeps\/395\" target=\"_blank\" rel=\"noopener\">Records<\/a> and <a href=\"https:\/\/openjdk.java.net\/jeps\/394\" target=\"_blank\" rel=\"noopener\">Pattern Matching for instanceof<\/a> as standard language features with <a href=\"https:\/\/openjdk.java.net\/jeps\/397\" target=\"_blank\" rel=\"noopener\">Sealed classes<\/a> continuing to be a <a href=\"https:\/\/openjdk.java.net\/jeps\/12\" target=\"_blank\" rel=\"noopener\">preview feature<\/a> (in the second preview).<\/p>\n<p>Fun fact &#8211; Records was voted the most popular Java 16 language feature by 1158 developers in this <a href=\"https:\/\/twitter.com\/eMalaGupta\/status\/1367274033184575497\" target=\"_blank\" rel=\"noopener\">Twitter poll<\/a>, with Pattern Matching for instanceof second.<\/p>\n<p>In this blog post, I will limit coverage of Java 16 to its language features, why you need them, and how you can start using them in <a href=\"https:\/\/www.jetbrains.com\/idea\/nextversion\/\" target=\"_blank\" rel=\"noopener\">IntelliJ IDEA<\/a>. You can use <a href=\"https:\/\/openjdk.java.net\/projects\/jdk\/16\/\" target=\"_blank\" rel=\"noopener\">this link<\/a> for a comprehensive list of the new Java 16 features. Let\u2019s get started.<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/s3otQAhPNZg\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"allowfullscreen\"><\/iframe><br \/>\n<!--more--><\/p>\n<h1>Records<\/h1>\n<p>Records introduce a new type declaration that simplifies the task of modeling your immutable data. Though it helps cut down on boilerplate code significantly, that isn\u2019t the primary reason for its introduction. Here\u2019s an example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">record Person(String name, int age) {}<\/pre>\n<p>With just one line of code, the preceding example defines a record <code>Person<\/code> with two components <code>name<\/code> and <code>age<\/code>. To create a record using IntelliJ IDEA 2021.1, select Record in the New Java Class dialog box. Fill in the name and you are good to go.<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-6-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-6.gif\" \/><\/p>\n<p>Let\u2019s quickly check the configuration of IntelliJ IDEA on your system to ensure you can get the code to run it. <\/p>\n<h2>IntelliJ IDEA Configuration<\/h2>\n<p>Java 16 features are supported in IntelliJ IDEA 2021.1, which is scheduled to be released this March. The early access versions of 2021.1 are already available. You can configure it to use Java 16 by selecting 16 as the Project SDK and choosing <em>16 (Preview) \u2013 Sealed types<\/em> in the Project language level for your Project and Modules settings. <\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-config.png\" alt=\"\" width=\"803\" \/><\/p>\n<p>You can also download Java 16 directly from IntelliJ IDEA. To do so, go to <em>Platform Settings<\/em> and click on <em>SDKs<\/em>, then click the \u2018+\u2019 sign at the top, choose <em>Download JDK<\/em>, then select the Vendor and version and the directory to download the JDK to.<\/p>\n<h3>Access sample code used in this blog post<\/h3>\n<p>All sample code used in this blog post is hosted at <a href=\"https:\/\/github.com\/malagupta\/Java16AndIntelliJIDEA\" target=\"_blank\" rel=\"noopener\">Github<\/a>.<\/p>\n<h2>Implicit members added to a record<\/h2>\n<p>The compilation process creates a full-blown class \u2013 a record is defined as a final class, extending the <code>java.lang.Record<\/code> class from the core Java API. For each of the components of the record Person, the compiler defines a final instance variable (<code>name<\/code> and <code>age<\/code>). Interestingly, the name of the getter method is the same as that of the data variable (it doesn\u2019t start with <code>get<\/code> or <code>is<\/code>). Since a record is supposed to be immutable, no setter methods are defined.<br \/>\nThe methods <code>toString()<\/code>, <code>hashCode()<\/code>, and <code>equals()<\/code> are also generated automatically for records.<\/p>\n<h2>Why use records<\/h2>\n<p>Imagine you want to persist the details of, say, a person to a file. Before the introduction of records, you would need to define a regular class with instance variables, accessor methods, and implement methods from the Object class (<code>toString()<\/code>, <code>hashcode()<\/code>, and <code>equals()<\/code>). Though IntelliJ IDEA can generate all this code for you easily, there is no way to tag this class as a data class, so it would still be read as a regular class. <\/p>\n<p>The following gif demonstrates how you can declare class <code>Person<\/code> as a regular class, generate code for it, implement the interface <code>Serializable<\/code> and run it to verify you can write it to a file and read from it:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-7-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-7.gif\" \/><\/p>\n<p>Now, let&#8217;s declare <code>Person<\/code> as a record using just one line of code with components <code>name<\/code> (String) and <code>age<\/code> (int). It implements the interface <code>Serializable<\/code> since we need to persist its instances to a file. Note that you can still use the same methods to persist it to a text file. Also, there are no changes in how you instantiate it (by using the new operator):<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-15-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-15.gif\" \/><\/p>\n<p>Record <code>Person<\/code> is just one example on how you can use Records. You can use records to model your data, without additional overhead of defining additional methods.<\/p>\n<h2>What you can and can\u2019t add to a record<\/h2>\n<p>Since the state of a record is defined using components in its declaration, it doesn\u2019t make much sense to allow the addition of instance variables (or fields) to a record. However, you can add static fields, and instance or static methods to a record, if you need them. Here\u2019s an example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public record Person(String name, int age) {\n   Person {\n       instanceCtr++;\n   }\n   private static int instanceCtr;\n   static int getInstanceCtr() {\n       return instanceCtr;\n   }\n}<\/pre>\n<h2>Modifying the default behavior of a constructor in a record<\/h2>\n<p>The default constructor of a record just initializes its state with the values you pass to it. You can change this default behavior if necessary, for example, to validate the parameter values before they are assigned.<\/p>\n<p>IntelliJ IDEA lets you insert a compact, canonical, or custom constructor in a record. For your information, a compact constructor doesn\u2019t have a parameter list, not even parentheses. A canonical constructor is one whose signature matches with the record\u2019s state description. And a custom constructor lets you choose the record components you want to pass to the constructor of a record. With all these constructors, you can add validation code. A compact constructor enables you to add code without adding the full boilerplate code.<\/p>\n<p>Let\u2019s see how you can insert a compact constructor using the Alt+Insert shortcut in IntelliJ IDEA, and add validation code to it:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-8-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-8.gif\" \/><\/p>\n<p>You can also add a canonical constructor to a record. This defines a parameter list \u2013 which must have the same names and order as those of the components of a record. A mismatch would result in a compilation error.<\/p>\n<p>By invoking context actions in IntelliJ IDEA (with Alt+Enter), you can easily convert a canonical constructor to a compact constructor:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-9-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-9.gif\" \/><\/p>\n<h2>Truly immutable data<\/h2>\n<p>Records are truly immutable \u2013 you can\u2019t change their field values using reflection ( if you haven\u2019t tried it out yet, you can change the value of immutable strings using reflection).<\/p>\n<p>Here is example code for a regular class, <code>Notebook<\/code>, which defines a private final field <code>pageCount<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public class NoteBook {\n   private final int pageCount;\n\n   public NoteBook(int pageCount) {\n       this.pageCount = pageCount;\n   }\n\n   public int getPageCount() {\n       return pageCount;\n   }\n\n   @Override\n   public String toString() {\n       return &quot;NoteBook{&quot; + &quot;pageCount=&quot; + pageCount + &#039;}&#039;;\n   }\n}<\/pre>\n<p>And here\u2019s the code for a record <code>Point<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public record Point(int x, int y) {\n}<\/pre>\n<p>The following code confirms that the private and final fields of a (regular) class can be changed using reflection, but records are a harder nut to crack:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">package com.jetbrains.java16.records;\nimport java.lang.reflect.Field;\n\npublic class UseReflection {\n   public static void main(String[] args) throws Exception {\n       changeFinalFieldValuesForNonRecords();\n       changeFinalForRecords();\n   }\n\n   private static void changeFinalFieldValuesForNonRecords()\n                throws NoSuchFieldException, IllegalAccessException {\n       final var noteBook = new NoteBook(10);\n       System.out.println(noteBook);\n\n       Field pageField = noteBook.getClass().getDeclaredField(&quot;pageCount&quot;);\n       pageField.setAccessible(true);\n       int newCount = 1000;\n       pageField.setInt(noteBook, newCount);\n\n       System.out.println(noteBook);\n   }\n\n   private static void changeFinalForRecords()\n                throws NoSuchFieldException, IllegalAccessException {\n       final var point = new Point(12, 35);\n       System.out.println(point);\n\n       Field xField = point.getClass().getDeclaredField(&quot;x&quot;);\n       xField.setAccessible(true);\n       int newVal = 1000;\n       xField.setInt(point, newVal);\n\n       System.out.println(point);\n   }\n}<\/pre>\n<h2>Defining a Generic record<\/h2>\n<p>You can define records with generics. Here\u2019s an example of a record called <code>Parcel<\/code>, which can store any object as its contents, and capture the parcel\u2019s dimensions and weight:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public record Parcel&lt;T&gt;(T contents,\n   double length,\n   double breadth,\n   double height,\n   double weight) {}<\/pre>\n<p>You can instantiate this record as follows:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">class Table{ \/* class code *\/ }\npublic class Java16 {\n   public static void main(String[] args) {\n       Parcel&lt;Table&gt; parcel = new Parcel&lt;&gt;(\nnew Table(), 200, 100, 55, 136.88);\n       System.out.println(parcel);\n   }\n}<\/pre>\n<h2>Converting Record to a regular class<\/h2>\n<p>If you are working with records but need to transition it to the codebase of an older Java version that doesn\u2019t support records, you can quickly convert a record to a regular class by using the context action Convert record to class or vice-versa by using the context action Convert to a record:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-10-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-10.gif\" \/><\/p>\n<h2>Records as components of record<\/h2>\n<p>A record component can be another record. In the following example, record <code>Automobile<\/code> defines one of its components as <code>Engine<\/code>, another record:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-11-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-11.gif\" \/><\/p>\n<h2>Adding annotations to record components<\/h2>\n<p>You can add an appropriate annotation to the components of a record, say, <code>@NotNull<\/code>, as demonstrated in the following gif:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-12-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-12.gif\" \/><\/p>\n<p>Developers often use third-party libraries like Jackson to persist value objects. Jackson supports records too. However, depending on the Jackson library version you are using (say, 2.11.3), you might need to annotate the components of your records using the annotation <code>@JsonProperty<\/code>, as follows: <\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">import com.fasterxml.jackson.annotation.JsonProperty;\n\npublic record Rectangle(\n       @JsonProperty(&quot;width&quot;) int width,\n       @JsonProperty(&quot;length&quot;) int length) {\n}<\/pre>\n<p><strong>If you are using Jackson 2.12.2 or later versions, you don\u2019t need to annotate your record components with <code>@JsonProperty<\/code>.<br \/>\n<\/strong><br \/>\nHere\u2019s some sample code you can use to persist and read records using Jackson:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public class ReadWriteRecordUsingJackson {\n\n   public static void main(String[] args) {\n       Rectangle rectangle = new Rectangle(20, 60);\n       writeToFileUsingJackson(rectangle);\n       System.out.println(readFromFileUsingJackson());\n   }\n\n   static void writeToFileUsingJackson(Object obj) {\n       try {\n           new ObjectMapper()\n                   .writeValue(new FileOutputStream(getFile()),\n                               obj);\n       } catch (IOException e) {\n           e.printStackTrace();\n       }\n   }\n\n   static Object readFromFileUsingJackson() {\n       Object retValue = null;\n       try {\n           retValue = new ObjectMapper()\n                        .readValue( new FileInputStream(getFile()),\n                                    Rectangle.class);\n       } catch (IOException e) {\n           e.printStackTrace();\n       }\n       return retValue;\n   }\n\n   private static File getFile() {\n       return new File(&quot;mydata.json&quot;);\n   }\n}<\/pre>\n<p>If you are working with a Maven project, you can add the following dependencies to your pom.xml:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">&lt;dependency&gt;\n   &lt;groupId&gt;com.fasterxml.jackson.core&lt;\/groupId&gt;\n   &lt;artifactId&gt;jackson-core&lt;\/artifactId&gt;\n   &lt;version&gt;2.12.2&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n   &lt;groupId&gt;com.fasterxml.jackson.core&lt;\/groupId&gt;\n   &lt;artifactId&gt;jackson-annotations&lt;\/artifactId&gt;\n   &lt;version&gt;2.12.2&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n   &lt;groupId&gt;com.fasterxml.jackson.core&lt;\/groupId&gt;\n   &lt;artifactId&gt;jackson-databind&lt;\/artifactId&gt;\n   &lt;version&gt;2.12.2&lt;\/version&gt;\n&lt;\/dependency&gt;<\/pre>\n<h2>Reading and Writing Records to a File<\/h2>\n<p>You can write records to streams and read them, like other class instances. Let your record implement a relevant interface like the <code>Serializable<\/code> interface. Here\u2019s example code, which will write to and read from a file:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">package com.jetbrains.java16.records;\nimport java.io.Serializable;\npublic record Person(String name, int age) implements Serializable {\n}\n\npackage com.jetbrains.java16.records;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport java.io.*;\npublic class ReadWriteObj {\n\n   public static void main(String[] args) throws Exception {\n       Person person = new Person(&quot;Java&quot;, 25);\n       writeToFile(person, &quot;..\/temp.txt&quot;);\n       System.out.println(readFromFile(&quot;..\/temp.txt&quot;));\n   }\n\n   static void writeToFile(Object obj, String path) {\n       try (ObjectOutputStream oos = \n                    new ObjectOutputStream(new FileOutputStream(path))){\n           oos.writeObject(obj);\n       } catch (IOException e) {\n           e.printStackTrace();\n       }\n   }\n   static Object readFromFile(String path) {\n       Object result = null;\n       try (ObjectInputStream ois = \n                    new ObjectInputStream(new FileInputStream(path))){\n           result = ois.readObject();\n       } catch (ClassNotFoundException | IOException e) {\n           e.printStackTrace();\n       }\n       return result;\n   }\n}<\/pre>\n<h2>Refactoring the signature of a Record<\/h2>\n<p>You can refactor a Record and modify the order of its components or types, modify their names, and add new or remove existing ones. IntelliJ IDEA has simplified how you apply Rename or Change Signature Refactorings. The changes would reflect in a record\u2019s canonical constructor and its instance creation:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-13-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-13.gif\" \/><\/p>\n<h2>A restricted identifier<\/h2>\n<p><code>record<\/code> is a restricted identifier (like <code>var<\/code>), but it isn\u2019t a regular keyword (yet). So, the following code is valid:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">int record = 10;\nvoid record() {}<\/pre>\n<p>However, you may want to refrain from using <code>record<\/code> as an identifier because such code will become confusing as more developers start using records.<\/p>\n<h2>Local records<\/h2>\n<p>You can define local records to model a domain object while you are processing values in a method. In the following example, the method <code>getTopPerformingStocks<\/code> finds and returns the names of the <code>Stock<\/code> with the highest value on a specified date.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">List&lt;String&gt; getTopPerformingStocks(List&lt;Stock&gt; allStocks, LocalDate date) {\n   \/\/ TopStock is a local record\n   record TopStock(Stock stock, double stockValue) {}\n\nreturn allStocks.stream()\n               .map(s -&gt; new TopStock(s, getStockValue(s, dateTime)))               .sorted(Comparator.comparingDouble(TopStock::value).reversed())\n               .limit(2)\n               .map(s -&gt; s.stock().name())\n               .collect(Collectors.toList());\n}<\/pre>\n<h2>Declaring implicit or explicit static members in an  inner class<\/h2>\n<p>Starting from Java 16, an inner class can explicitly or implicitly define static members, including records.<\/p>\n<h2>Local interfaces and enums<\/h2>\n<p>You can declare local enums and interfaces. You can encapsulate your data or business logic, which is local to a method, within the method.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public void createLocalInterface() {\n   interface LocalInterface {\n       void aMethod();\n   }\n   \/\/ Code to use LocalInterface\n}\n\npublic void createLocalEnum() {\n   enum Color {RED, YELLOW, BLUE}\n   \/\/ Code to use enum Color\n}<\/pre>\n<p>However, they cannot capture any context variable. For example, for the local enum <code>Data<\/code>, the enum constants <code>FOO<\/code> and <code>BAR<\/code> can\u2019t be created using the method parameter input in the method <code>test()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">void test(int input) {\n   enum Data {\n       FOO(input), BAR(input*2); \/\/ Error. Can\u2019t refer to input\n\n       private final int i;\n\n       Data(int i) {\n           this.i = i;\n       }\n   }\n}<\/pre>\n<h1>Sealed classes and interfaces (a preview feature)<\/h1>\n<p>The language syntax of Sealed types enables you to restrict the classes or interfaces that can extend or implement them. The goal of this language feature is to let you define the possible hierarchies in your business domain in a declarative manner. But why would you ever need to create restricted hierarchies?<\/p>\n<h2>Need for creating restricted hierarchies<\/h2>\n<p>Imagine you are creating an application that helps its users with gardening activities. Depending on the type of plant, a gardener might need to do different activities. Let\u2019s <a href=\"https:\/\/github.com\/malagupta\/Java16AndIntelliJIDEA\" target=\"_blank\" rel=\"noopener\">model the plant hierarchy<\/a> as follows (I\u2019m not detailing the classes on purpose):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">class Plant {}\n\nclass Herb extends Plant {}\nclass Shrub extends Plant {}\nclass Climber extends Plant {}\n\nclass Cucumber extends Climber {}<\/pre>\n<p>The following code is an example of how the Gardener class might use this hierarchy:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">\npublic class Gardner {\n   int process(Plant plant) {\n       if (plant instanceof Cucumber) {\n           return harvestCucumber(plant);\n       } else if (plant instanceof Climber) {\n           return sowClimber(plant);\n       } else if (plant instanceof Herb) {\n           return sellHerb(plant);\n       } else if (plant instanceof Shrub) {\n           return pruneShrub(plant);\n       } else {\n           System.out.println(&quot;Unreachable CODE. Unknown Plant type&quot;);\n           return 0;\n       }\n   }\n\n   private int pruneShrub(Plant plant) {...}\n   private int sellHerb(Plant plant) {...}\n   private int sowClimber(Plant plant) {...}\n   private int harvestCucumber(Plant plant) {...}\n}<\/pre>\n<p>The problem code is the assumption that a developer has to deal with in the last else construct &#8211; defining actions even though the developer knows that all possible types of the method parameters plant have been addressed. Though it might look unreachable now, what happens if another developer adds a class to this hierarchy? Sealed classes can impose this restriction on the hierarchies at the language level.<\/p>\n<h2>Define secure hierarchies with sealed classes<\/h2>\n<p>With the <a href=\"https:\/\/openjdk.java.net\/jeps\/8223002#:~:text=Contextual%20keyword%3A%20A%20sequence%20of,declarations%2C%20since%20Java%209\" target=\"_blank\" rel=\"noopener\">contextual keyword<\/a> <code>sealed<\/code>, you can declare a class as a sealed class. A sealed class uses the contextual keyword <code>permits<\/code> to list the classes that can extend it directly. Its subclasses can either be <code>final<\/code>, <code>non-sealed<\/code>, or <code>sealed<\/code>.<\/p>\n<p>The following gif shows how you can use IntelliJ IDEA to change the declaration of a regular class to a sealed class (by using the context action \u2018Seal class\u2019). By default IntelliJ IDEA declares all derived classes as non-sealed. You can modify it to be final or sealed:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-1-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-1.gif\" \/><\/p>\n<p>Here\u2019s the modified code for reference:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">\nsealed public class Plant permits Herb, Shrub, Climber {\n}\n\nfinal class Herb extends Plant {}\nnon-sealed class Shrub extends Plant {}\nsealed class Climber extends Plant permits Cucumber{}\n\nfinal class Cucumber extends Climber {}<\/pre>\n<p>By allowing a predefined set of classes to extend your class, you can decouple accessibility from extensibility. You can make your sealed class accessible to other packages and modules, and you can still control who can extend it.<\/p>\n<p>In the past, to prevent classes from being extended, developers created package-private classes. But, this also meant that these classes had limited accessibility. Another approach to prevent extension was to create public classes with private or package-private constructors. Though it enabled a class to be visible, it gave limited control on the exact types that could extend your class. <\/p>\n<p>This is no longer the case if you use sealed classes. The goal of the Sealed types is to model your business domain, so that you process it in a definitive manner.<\/p>\n<p>You can\u2019t create another class, say, <code>AquaticPlant<\/code>, that tries to extend the sealed class <code>Plant<\/code>, without adding it to the <code>permits<\/code> clause of the class <code>Plant<\/code>. As shown in the following gif, this is a compilation error:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-2-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-2.gif\" \/><\/p>\n<h2>Revisiting processing of Plant types in class Gardner<\/h2>\n<p>After creating a sealed hierarchy, you will be able to process an instance from the hierarchy in a precise way, and won\u2019t need to deal with any unknown implementations. The <code>process<\/code> method in class <code>Gardner<\/code> will work with no chance of running the <code>else<\/code> clause. However, the syntax of the <code>if<\/code>&#8211;<code>else<\/code> construct will still need you to define the <code>else<\/code> part (this may change in a future Java version).<\/p>\n<p>Type-test-patterns, introduced with Pattern Matching for instanceof in Java 14, might be added to the switch expressions in future Java versions. With the enhanced switch expressions, you are able to work with an exhaustive list of extended types. This could let you eliminate the definition of code to execute for an unmatched Plant type passed to the method <code>processInAFutureJavaVersion()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">\n\/\/ This code doesn&#039;t work in Java 16.\n\/\/ It would work in a future Java version after the addition of \n\/\/ type-test-pattern to the switch expressions\nint processInAFutureJavaVersion(Plant plant) {\n   return switch (plant) {\n       case Cucumber c -&gt; c.harvestCucumber();\n       case Climber cl -&gt; cl.sowClimber();\n       case Herb h -&gt; h.sellHerb();\n       case Shrub s -&gt; s.pruneShrub();\n   }\n}<\/pre>\n<h2>Package and module restrictions<\/h2>\n<p>Sealed classes and their implementations can\u2019t span across multiple Java modules. <\/p>\n<p>If a sealed base class is declared in a named Java module, all its implementations must be defined in the same module. However, they can appear in different packages. <\/p>\n<p>For a sealed class declared in an unnamed Java module, all its implementations must be defined in the same package.<\/p>\n<h2>Rules for base and extended classes<\/h2>\n<p>The classes that extend a sealed class must either be final, non-sealed, or sealed. A final class prohibits further extension. A non-sealed class allows other classes to extend it. And a sealed subclass must follow the same set of rules as the parent base class \u2013 it could be extended by an explicit list of other classes.<\/p>\n<h2>Abstract sealed base class<\/h2>\n<p>A sealed class can be abstract too. The extended classes could be defined as abstract or concrete classes. Here\u2019s the modified code which adds an abstract method <code>grow()<\/code> to the class <code>Plant<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">sealed abstract public class Plant permits Herb, Shrub, Climber {\n   abstract void grow();\n}\n\npublic final class Shrub extends Plant {\n   @Override\n   void grow() {\n   }\n}\n\npublic non-sealed abstract class Herb extends Plant {}\n\npublic sealed class Climber extends Plant permits Cucumber{\n   @Override\n   void grow() {\n   }\n}\n\nfinal class Cucumber extends Climber {}<\/pre>\n<h2>Implicit subclasses<\/h2>\n<p>If you define a sealed class and its derived classes in the same source file, you can omit the contextual keyword permits and the name of the derived classes that are included in the declaration of a sealed class. In this case, the compiler can infer the hierarchy.<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-3-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-3.gif\" \/><\/p>\n<h1>Sealed interfaces<\/h1>\n<p>Unlike classes, interfaces can not define constructors. Before the introduction of sealed classes, a public class could define a private or package-private constructor to limit its extensibility, but interfaces couldn\u2019t do that. <\/p>\n<p>A sealed interface allows you to explicitly specify the interfaces that can extend it and the classes that can implement it. It follows rules similar to sealed classes. <\/p>\n<p>However, since you can\u2019t declare an interface using the modifier final \u2013 because doing so  would clash with its purpose, as interfaces are meant to be implemented \u2013 an inheriting interface can be declared using either sealed or non-sealed modifiers. The permits clause of an interface declaration lists the classes that can directly implement a sealed interface and interfaces that can extend it. An implementing class can be either final, sealed, or non-sealed:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-4-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-4.gif\" \/><\/p>\n<p>Here\u2019s the code for reference:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">sealed public interface Move permits Athlete, Jump, Kick {\n}\n\nfinal class Athlete implements Move {}\nnon-sealed interface Jump extends Move {}\nsealed interface Kick extends Move permits Karate {}\n\nfinal class Karate implements Kick {}<\/pre>\n<h2>Sealed classes and Java API<\/h2>\n<p>Soon, you might see the addition of sealed classes and interfaces to the core Java API too. Check out the API Note for the interface <code>ConstantDesc<\/code> from the package <code>java.lang.constant<\/code>:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-ConstantDesc.png\" alt=\"\" width=\"803\" \/><\/p>\n<p>Also, class <code>java.lang.Class<\/code> adds two methods <code>getPermittedSubclasses()<\/code><br \/>\nand <code>isSealed()<\/code> for working with the sealed types. You can also use them to enumerate the complete sealed hierarchy at runtime, which can be useful.<\/p>\n<h2>Stronger code analysis with closed list of subclasses<\/h2>\n<p>With sealed classes and interfaces, you can have an explicit list of inheritors that is known to the compiler, IDE and the runtime (via reflection). This closed list of subclasses makes the code analysis more powerful.<\/p>\n<p>For example, consider the following completely sealed hierarchy of <code>WritingDevice<\/code> (which doesn\u2019t have non-sealed subtypes):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">interface Erasable {}\n\nsealed class WritingDevice permits Pen, Pencil {}\nfinal class Pencil extends WritingDevice {}\nsealed class Pen extends WritingDevice permits Marker {}\nfinal class Marker extends Pen {}<\/pre>\n<p>Now, instanceof and casts can check the complete hierarchy statically. Code on line1 and line2 are compilation errors. The compiler checks all the inheritors from the permits list and finds that no one of them implements the <code>Erasable<\/code> or the <code>CharSequence<\/code> interface:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">class UseWritingDevice {\n   static void write(WritingDevice pen) {\n       if (pen instanceof Erasable) {                   \/\/ line1\n       }\n       CharSequence charSequence = ((CharSequence) pen);\/\/ line2\n   }\n}<\/pre>\n<p>The following gif demonstrates it in IntelliJ IDEA:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-14-cover.png\" alt=\"\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2021\/03\/java16-14.gif\" \/><\/p>\n<p>Let\u2019s now move on and look at another next language feature in Java 16 \u2013 Pattern Matching for instanceof.<\/p>\n<h1>Pattern Matching for instanceof<\/h1>\n<p>Many Java developers use the instanceof operator to check whether a given reference variable is of a certain type. They compare a reference variable to a type by using the instanceof operator. If the result is true, the next obvious step is to explicitly cast it to the type they compared it with to access its members. These steps have an obvious repetition here, like <em>compare-ifResultTrue-cast<\/em>.<\/p>\n<p>Here\u2019s an example of code that can be commonly found in code bases:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">void outputValueInUppercase(Object obj) {\n   if (obj instanceof String) {\n       String s = (String) obj;\n       System.out.println(s.toUpperCase());\n   }\n}<\/pre>\n<p>Pattern Matching for instanceof removes the repetition by introducing a pattern variable with the instanceof operator. If the instanceof condition is true, the pattern variable binds to the variable being compared, which prevents the need to define an additional variable or for explicit casting to use its members.<br \/>\nIn IntelliJ IDEA, you can invoke context-sensitive actions on the variable <code>s<\/code> (by using Alt+Enter or by clicking the light bulb icon) and select Replace <code>s<\/code> with pattern variable to use pattern matching:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-firstconversion-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-firstconversion.gif\" \/><\/p>\n<p>This modification introduces the pattern variable <code>s<\/code> (on line 5), which appears right after type <code>String<\/code>. This saves you from either defining a new variable or explicitly casting it to String before you could call the method <code>toUpperCase()<\/code> on it.<\/p>\n<p>Until Java 15, pattern variables were final local variables, declared and defined at the same place. However, with Java 16, pattern variables are no longer final.<\/p>\n<h2>Scope of pattern variable<\/h2>\n<p>The scope of the pattern variable is limited. If you try to access it in the else block, you\u2019ll receive an error.<\/p>\n<p>Though it might be confusing, if the class PatternMatching defines an instance or static variable with the same name as the pattern variable (<code>s<\/code>), the preceding code will compile. In this case, s in the else block will not refer to the pattern variable introduced in the <code>if<\/code> block:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-scope-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-scope.gif\" \/><\/p>\n<h2>Simplifying conditional expressions<\/h2>\n<p>The simplicity of pattern matching might be deceptive. Here\u2019s an example of how developers usually override the <code>equals()<\/code> method for a class, in this case, <code>Monitor<\/code>, with two fields \u2013 <code>model<\/code> (String value) and <code>price<\/code> (double value):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public class Monitor {\n  String model;\n  double price;\n  @Override\n  public boolean equals(Object o) {\n      if (o instanceof Monitor) {\n          Monitor other = (Monitor) o;\n          if (model.equals(other.model) &amp;&amp; price == other.price) {\n              return true;\n          }\n      }\n      return false;\n  }\n}<\/pre>\n<p>This is how the <code>equals()<\/code> method could be simplified by using pattern matching for instanceof and the further simplification of <code>if<\/code> statements:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-equals-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-equals.gif\" \/><\/p>\n<h2>Pattern matching and out-of-the-box support for existing intentions in IntelliJ IDEA<\/h2>\n<p>The real strength of Pattern Matching for instanceof is in how it can be used with various other intentions. For example, the following code merges if statements, introduces a pattern variable, and inlines a variable:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-demo2-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-demo2.gif\" \/><\/p>\n<h2>Simplifying usages of multiple instanceof in a code block<\/h2>\n<p>To look for places where you can use Pattern Matching for instanceof, spot usages of the instanceof operator, and explicit casting of variables. For instance, the following example has multiple occurrences of the instanceof operator with explicit casting. Let\u2019s simplify it:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-demo4-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-demo4-ver2.gif\" \/><\/p>\n<h2>Inlining of pattern variables<\/h2>\n<p>If you don\u2019t need the pattern variables, you can inline them with Inline pattern variable refactoring by using the shortcut Ctrl+Alt+N on Win and Linux\/ \u2325\u2318N on macOS. After you do so, all its usages would be replaced with explicit casting.<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-inline-pattern-variable-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-inline-pattern-variable.gif\" \/><\/p>\n<h2>Automatic pattern introduction on \u2018extract variable\u2019 refactoring<\/h2>\n<p>If you extract a variable from a cast expression, and IntelliJ IDEA detects that there were instanceof checks made before, then instead of creating a new local variable it just converts the instanceof to the pattern.<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-extract-cast-variable-cover.png\" alt=\"\" width=\"803\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/03\/idea-Java14-instanceof-extract-cast-variable.gif\" \/><\/p>\n<h1>Preview Features<\/h1>\n<p>In their second preview, sealed classes continue to be a preview feature in Java 16.<\/p>\n<p>With Java\u2019s new release cadence of six months, new language features are released as preview features. They may be reintroduced in later Java versions in the second or third preview, with or without changes. Once they are stable enough, they may be added to Java as a standard language feature. <\/p>\n<p>Preview language features are complete but not permanent, which essentially means that these features are ready to be used by developers, although their finer details could change in future Java releases depending on developer feedback. Unlike an API, language features can\u2019t be deprecated in the future. So, if you have feedback about any of the preview language features, feel free to share it on the JDK mailing list (free registration required).<\/p>\n<p>Because of how these features work, IntelliJ IDEA is committed to only supporting preview features for the current JDK. Preview language features can change across Java versions, until they are dropped or added as a standard language feature. Code that uses a preview language feature from an older release of the Java SE Platform might not compile or run on a newer release. For example, Switch Expressions in Java 12 were released with the usage of break to return a value from its branch, which was later changed to yield. Support for using break to return a value from Switch Expressions has already been dropped in IntelliJ IDEA.<\/p>\n<h1>Summary<\/h1>\n<p>IntelliJ IDEA is not only committed to supporting new Java features, but also to ensuring that our existing intentions and inspections work with them. <\/p>\n<p>IntelliJ IDEA 2021.1 supports all the new language features from Java 16. Try out Sealed classes and interfaces, Records, and Pattern Matching for instanceof today.<\/p>\n<p>We love to hear from our users. Don\u2019t forget to submit your feedback regarding the support for these features in IntelliJ IDEA.<\/p>\n<p>Happy Developing!<\/p>\n","protected":false},"author":921,"featured_media":122141,"comment_status":"closed","ping_status":"closed","template":"","categories":[808],"tags":[6502,3374,155,6500,3390,3389,6291,6503],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea\/122140"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/idea"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/921"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=122140"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea\/122140\/revisions"}],"predecessor-version":[{"id":145082,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea\/122140\/revisions\/145082"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media\/122141"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=122140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=122140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=122140"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=122140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}