{"id":6570,"date":"2020-11-20T05:17:36","date_gmt":"2020-11-20T10:17:36","guid":{"rendered":"http:\/\/springframework.guru\/?p=6570"},"modified":"2024-10-21T06:37:49","modified_gmt":"2024-10-21T10:37:49","slug":"using-records-in-java","status":"publish","type":"post","link":"https:\/\/springframework.guru\/using-records-in-java\/","title":{"rendered":"Using Records in Modern Java Development"},"content":{"rendered":"<p>Java 14 introduces a new feature called <a href=\"https:\/\/openjdk.org\/jeps\/359\" target=\"_blank\" rel=\"noopener noreferrer\">Records<\/a>. In Java, <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/14\/docs\/api\/java.base\/java\/lang\/Record.html\" target=\"_blank\" rel=\"noopener noreferrer\">Record<\/a> is a special type of Java class.\u00a0It is intended to hold pure immutable data in it. The syntax of a record is concise and short as compared to a normal class<\/p>\n<p>In this post, I will explain why do we need Java records and how to use them.<\/p>\n<h2>Why Java Records?<\/h2>\n<p>Whenever you write a Java class, you have to add a lot of boilerplate code. Like<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li>Getter and setter for each field<\/li>\n<li>A public constructor<\/li>\n<li>Override the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">hashCode()<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">equals()<\/code> methods of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Object<\/code> class<\/li>\n<li>Override the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">toString()<\/code> method of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Object<\/code> class<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>So, if you have to create a Java class, say <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Student<\/code>, you will have all these functions included.<\/p>\n<p>An example <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Student<\/code> class with boilerplate code is this.<br \/>\n<strong>Student.java<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">public class Student {\n\n   private int id;\n   private String firstName;\n   private String lastName;\n   private int grade;\n\n   public Student() {\n   }\n   public Student(int id, String firstName, String lastName, int grade) {\n      this.id = id;\n      this.firstName = firstName;\n      this.lastName = lastName;\n      this.grade = grade;\n   }\n\n   public int getId() {\n      return id;\n   }\n\n   public void setId(int id) {\n      this.id = id;\n   }\n\n   public String getFirstName() {\n      return firstName;\n   }\n\n   public void setFirstName(String firstName) {\n      this.firstName = firstName;\n   }\n\n   public String getLastName() {\n      return lastName;\n   }\n\n   public void setLastName(String lastName) {\n      this.lastName = lastName;\n   }\n\n   public int getGrade() {\n      return grade;\n   }\n\n   public void setGrade(int grade) {\n      this.grade = grade;\n   }\n\n\n   @Override\n   public String toString() {\n      return \"StudentClass{\" +\"id=\" + id + \", firstName='\" + firstName + '\\'' +\n      \", lastName='\" + lastName + '\\'' +\", grade=\" + grade + '}';\n   }\n\n   @Override\n   public boolean equals(Object o) {\n      if (this == o) return true;\n      if (o == null || getClass() != o.getClass()) return false;\n      StudentClass that = (StudentClass) o;\n      return id == that.id &amp;&amp;\n          grade == that.grade &amp;&amp;\n          Objects.equals(firstName, that.firstName) &amp;&amp;\n          Objects.equals(lastName, that.lastName);\n   }\n\n@Override\n    public int hashCode() {\n      return Objects.hash(id, firstName, lastName, grade);\n   }\n}\n<\/pre>\n<p>As you can see in the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Student<\/code>class, we have getter and setter methods for every field. We have an empty constructor, a parameterized constructor, and so on.<\/p>\n<p>If you are using an IDE, such as Intelli J these boilerplate codes can be generated. So, you as a programmer don\u2019t need to type it on your own, but still, you will need to generate them. But, in the end, your class gets bulky and can cause readability issues for other developers.<\/p>\n<p>The main advantage of using records is that the methods like <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">equals()<\/code>,\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">hashCode()<\/code>,<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">\u00a0toString()<\/code>,\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">constructor()<\/code>\u00a0are already generated. It makes the code short and easy to understand.<\/p>\n<h2>Record Syntax<\/h2>\n<p>The syntax of a Java Record modeling a Student is as follows.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">public record Student(int id, String firstName, String lastName,int age, String PNo) {}\n<\/pre>\n<p>The preceding line of code is equivalent to the entire Student class I showed previously. This obviously saves a lot of time and reduces the boilerplate code.<\/p>\n<p>Now, I have a Student record with four components: id, firstName, lastName, and grade.<\/p>\n<p>Since Java Records is a <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/15\/language\/preview-language-and-vm-features.html\" target=\"_blank\" rel=\"noopener noreferrer\">preview language feature<\/a> in JDK 14, you need to enable preview features to use them. \u00a0A preview language feature means that even though this feature is ready to be used by developers, it could be changed in a future Java release. They may either be removed in a future release or upgraded to permanent features, depending on the feedback received on this feature by developers.<\/p>\n<p>So, to enable the Java 14 preview features you need to use <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">--enable-preview -source 14<\/code> in the command line.<\/p>\n<p>Now, let\u2019s compile it like this.<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">javac --enable-preview --release 14 Student.java<\/code>.<\/p>\n<h2>How to Use a Java Record?<\/h2>\n<p>A Java record can be used in the same way as a Java class.<\/p>\n<p>Here is the code.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">Student student1 = new Student(1,\"Harry\",\"styles\",10);\nStudent student2 = new Student(4,\"Louis\",\"Tomlinson\",11);\n\n\/\/to string\nSystem.out.println(student1);\nSystem.out.println(student2);\n\n\/\/accessing fields\nSystem.out.println(\"First Name : \" +student1.firstName());\nSystem.out.println(\"Last Name : \" +student1.lastName());\nSystem.out.println(student1.toString());\n\n\/\/equals to\nSystem.out.println(student1.equals(student2));\n\n\/\/hash code\nSystem.out.println(student1.hashCode());\n<\/pre>\n<p>As you can see from the code without creating functions like <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">hashCode()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">equals()<\/code> we can use them in records.<\/p>\n<p>Now, let\u2019s use the\u00a0<a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/technotes\/tools\/windows\/javap.html\" target=\"_blank\" rel=\"noopener noreferrer\"><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">javap<\/code><\/a>command to see what happens when a Record is compiled.<\/p>\n<p>From command prompt\/IntelliJ terminal, run <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">javap Student.class<br \/>\n<\/code><br \/>\n<a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-6647\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1-1024x143.png\" alt=\"\" width=\"1024\" height=\"143\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1-1024x143.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1-300x42.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1-768x107.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1-848x118.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1-410x57.png 410w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-221-1.png 1358w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>Here is the code of the decompiled <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Student<\/code> class.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">public final class Student extends java.lang.Record {\nprivate final int id;\nprivate final java.lang.String firstName;\nprivate final java.lang.String lastName;\nprivate final int grade;\npublic static java.lang.String UNKNOWN_GRADE\n\npublic Student(int id, java.lang.String firstName, java.lang.String lastName, int grade) {\n\/* compiled code *\/ }\n\npublic static java.lang.String getUnknownGrade() {\/* compiled code *\/ }\n\npublic java.lang.String toString() {\/* compiled code *\/}\n\npublic final int hashCode() {\/* compiled code *\/}\n\npublic final boolean equals(java.lang.Object o) {\/* compiled code *\/ }\n\npublic int id() {\/* compiled code *\/ }\n\npublic java.lang.String firstName() {\/* compiled code *\/ }\n\npublic java.lang.String lastName() {\/* compiled code *\/}\n\npublic int grade() {\/* compiled code *\/}\n}\n<\/pre>\n<p>As you can see in the preceding code, no setter methods got created. This is because the type of record is final and immutable. Also, notice that the names of the getter methods are not preceded by <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">get<\/code>. Rather they contain the attribute name only.<\/p>\n<p>More importantly, note that the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Student<\/code> class extends, <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/14\/docs\/api\/java.base\/java\/lang\/Record.html\" target=\"_blank\" rel=\"noopener noreferrer\"><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">java.lang.Record<\/code><\/a>. All Java Records implicitly extend <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">java.lang.Record <\/code> class. However, you directly cannot extend the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">java.lang.Record<\/code> class in your code.<\/p>\n<p>The compiler will reject the attempt, like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">$ javac --enable-preview -source 14 Student.java\n\nStudent.java:3: error: records cannot directly extend Record\npublic final class Student extends Record {\n             ^\nNote: Student.java uses preview language features.\nNote: Recompile with -Xlint:preview for details.\n1 error\n<\/pre>\n<p>Also in the decompiled class, notice that a declares\u00a0methods like <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">equals()<\/code>,\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">hashCode()<\/code>, and\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">toString()<\/code>\u00a0to be abstract. These abstract methods rely on\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">invokedynamic<\/code> to dynamically invoke the appropriate method which contains the implicit implementation. You can find more information on invokedynamic <a href=\"http:\/\/cr.openjdk.java.net\/~vlivanov\/talks\/2015-Indy_Deep_Dive.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<p>Also, all the fields in the record declaration are specified as final.<\/p>\n<h2>Instance Methods in Record<\/h2>\n<p>Just like java classes, we can also include methods in a record definition. Here is an example of the Student Java Record definition from earlier sections. I have added an instance method named <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">nameAsUpperCase()<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">public record Student(int id,String firstName,String lastName,int grade) {\n\npublic String nameAsUpperCase(){\nreturn firstName.toUpperCase();\n}\n\n}<\/pre>\n<p>By simply invoking the function <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">nameAsUpperCase()<\/code> we will get the first name in the upper case.<\/p>\n<p>The test code is this.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">System.out.println(\"First Name : \" +student1.nameAsUpperCase());<\/pre>\n<p>Let\u2019s run the code and see the output.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-6648\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222-1024x102.png\" alt=\"instance method\" width=\"1024\" height=\"102\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222-1024x102.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222-300x30.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222-768x77.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222-848x84.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222-410x41.png 410w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-222.png 1365w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<h2>Static Methods in Record<\/h2>\n<p>We can also add static methods and variables inside the record definition.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">public record Student(int id, String firstName,String lastName,int grade) {\npublic static String UNKNOWN_GRADE = \"grade not known\" ;\n\npublic static String getUnknownGrade() {\n    return UNKNOWN_GRADE;\n }\n}\n<\/pre>\n<p>From the main class, we can call the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">getUnknownGrade() <\/code>function.<\/p>\n<p>The test code is this.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">System.out.println(student1.getUnknownGrade());<\/pre>\n<p>The output is as follows.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-6649\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1-1024x107.png\" alt=\"static method\" width=\"1024\" height=\"107\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1-1024x107.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1-300x31.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1-768x81.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1-848x89.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1-410x43.png 410w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-223-1.png 1353w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>We can also add constructors inside the record definition. There are three types of record constructors. They are compact, canonical, and custom constructors.<\/p>\n<p>A compact constructor doesn\u2019t have any arguments. It doesn\u2019t even have parenthesis.<\/p>\n<p>This is a typical example of a compact constructor.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">public Student{\nif(id &lt; 0)\n    throw new IllegalArgumentException(\"student id cannot be negative\");\n}\n<\/pre>\n<p>Since id cannot be negative, I am adding an exception here.<\/p>\n<p>This is the test code.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">Student student = new Student(-1,\"loius\",\"lee\",4);\nSystem.out.println(student);\n<\/pre>\n<p>As you can see from the output we get an error message.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-6645\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224-1024x102.png\" alt=\"error message\" width=\"1024\" height=\"102\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224-1024x102.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224-300x30.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224-768x76.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224-848x84.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224-410x41.png 410w, https:\/\/springframework.guru\/wp-content\/uploads\/2020\/11\/Screenshot-224.png 1360w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>A canonical constructor takes all the members as its parameters.<\/p>\n<p>If you modify a canonical constructor, then it becomes a custom constructor.<\/p>\n<p>You can only go for any one of the three constructors mentioned above at one time. This is because adding multiple constructors to a record like a regular class is not allowed.<\/p>\n<h2>Summary<\/h2>\n<p>Java Records is a great way to reduce boilerplate code without sacrificing the reliability of an immutable class.<\/p>\n<p>If you have written code for enterprise applications, you might have encountered <a href=\"https:\/\/projectlombok.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Lombok<\/a>, a tool to also reduce boilerplate code.<\/p>\n<p>There have been talks about Java Records replacing libraries like Lombok, but it is not so. Both are different tools for different things. There is some superficial overlap, but don&#8217;t let that distract you.<\/p>\n<p>Lombok or similar boilerplate code generation libraries are largely about syntactic convenience. They are typically pre-loaded with some known useful patterns of code. They automate the patterns, according to the annotations you add to your class. Such libraries are purely about the convenience of implementing data-carrying classes.<\/p>\n<p>On the other hand, Java Records are a semantic feature. They provide a first-class means for modeling data-only aggregates. They also are designed to close a possible gap in Java\u2019s type system. In addition, as we saw, Records provide language-level syntax for a common programming pattern.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Java 14 introduces a new feature called Records. In Java, Record is a special type of Java class.\u00a0It is intended to hold pure immutable data in it. The syntax of a record is concise and short as compared to a normal class In this post, I will explain why do we need Java records and [&hellip;]<a href=\"https:\/\/springframework.guru\/using-records-in-java\/\" class=\"df-link-excerpt\">Continue reading<\/a><\/p>\n","protected":false},"author":111,"featured_media":4592,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[20],"tags":[335],"class_list":["post-6570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-records"],"jetpack_publicize_connections":[],"aioseo_notices":[],"modified_by":"jt","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/03\/Banner560x292_07web.jpg","jetpack_shortlink":"https:\/\/wp.me\/p5BZrZ-1HY","_links":{"self":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/6570"}],"collection":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/users\/111"}],"replies":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/comments?post=6570"}],"version-history":[{"count":10,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/6570\/revisions"}],"predecessor-version":[{"id":8234,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/6570\/revisions\/8234"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media\/4592"}],"wp:attachment":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media?parent=6570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/categories?post=6570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/tags?post=6570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}